+5
-8
appview/db/issues.go
+5
-8
appview/db/issues.go
···
101
101
pLower := FilterGte("row_num", page.Offset+1)
102
102
pUpper := FilterLte("row_num", page.Offset+page.Limit)
103
103
104
-
pageClause := ""
105
-
if page.Limit > 0 {
106
-
args = append(args, pLower.Arg()...)
107
-
args = append(args, pUpper.Arg()...)
108
-
pageClause = " where " + pLower.Condition() + " and " + pUpper.Condition()
109
-
}
104
+
args = append(args, pLower.Arg()...)
105
+
args = append(args, pUpper.Arg()...)
106
+
pagination := " where " + pLower.Condition() + " and " + pUpper.Condition()
110
107
111
108
query := fmt.Sprintf(
112
109
`
···
131
128
%s
132
129
`,
133
130
whereClause,
134
-
pageClause,
131
+
pagination,
135
132
)
136
133
137
134
rows, err := e.Query(query, args...)
···
247
244
}
248
245
249
246
func GetIssues(e Execer, filters ...filter) ([]models.Issue, error) {
250
-
return GetIssuesPaginated(e, pagination.Page{}, filters...)
247
+
return GetIssuesPaginated(e, pagination.FirstPage(), filters...)
251
248
}
252
249
253
250
func AddIssueComment(e Execer, c models.IssueComment) (int64, error) {
+4
-7
appview/db/notifications.go
+4
-7
appview/db/notifications.go
···
60
60
whereClause += " AND " + condition
61
61
}
62
62
}
63
-
pageClause := ""
64
-
if page.Limit > 0 {
65
-
pageClause = " limit ? offset ? "
66
-
args = append(args, page.Limit, page.Offset)
67
-
}
68
63
69
64
query := fmt.Sprintf(`
70
65
select id, recipient_did, actor_did, type, entity_type, entity_id, read, created, repo_id, issue_id, pull_id
71
66
from notifications
72
67
%s
73
68
order by created desc
74
-
%s
75
-
`, whereClause, pageClause)
69
+
limit ? offset ?
70
+
`, whereClause)
71
+
72
+
args = append(args, page.Limit, page.Offset)
76
73
77
74
rows, err := e.QueryContext(context.Background(), query, args...)
78
75
if err != nil {
+41
-13
appview/issues/issues.go
+41
-13
appview/issues/issues.go
···
78
78
issue, ok := r.Context().Value("issue").(*models.Issue)
79
79
if !ok {
80
80
l.Error("failed to get issue")
81
-
rp.pages.Error404(w)
81
+
rp.pages.Error404(w, pages.ErrorPageParams{
82
+
LoggedInUser: user,
83
+
})
82
84
return
83
85
}
84
86
···
99
101
)
100
102
if err != nil {
101
103
l.Error("failed to fetch labels", "err", err)
102
-
rp.pages.Error503(w)
104
+
rp.pages.Error503(w, pages.ErrorPageParams{
105
+
LoggedInUser: user,
106
+
})
103
107
return
104
108
}
105
109
···
132
136
issue, ok := r.Context().Value("issue").(*models.Issue)
133
137
if !ok {
134
138
l.Error("failed to get issue")
135
-
rp.pages.Error404(w)
139
+
rp.pages.Error404(w, pages.ErrorPageParams{
140
+
LoggedInUser: user,
141
+
})
136
142
return
137
143
}
138
144
···
275
281
issue, ok := r.Context().Value("issue").(*models.Issue)
276
282
if !ok {
277
283
l.Error("failed to get issue")
278
-
rp.pages.Error404(w)
284
+
rp.pages.Error404(w, pages.ErrorPageParams{
285
+
LoggedInUser: user,
286
+
})
279
287
return
280
288
}
281
289
···
324
332
issue, ok := r.Context().Value("issue").(*models.Issue)
325
333
if !ok {
326
334
l.Error("failed to get issue")
327
-
rp.pages.Error404(w)
335
+
rp.pages.Error404(w, pages.ErrorPageParams{
336
+
LoggedInUser: user,
337
+
})
328
338
return
329
339
}
330
340
···
368
378
issue, ok := r.Context().Value("issue").(*models.Issue)
369
379
if !ok {
370
380
l.Error("failed to get issue")
371
-
rp.pages.Error404(w)
381
+
rp.pages.Error404(w, pages.ErrorPageParams{
382
+
LoggedInUser: user,
383
+
})
372
384
return
373
385
}
374
386
···
456
468
issue, ok := r.Context().Value("issue").(*models.Issue)
457
469
if !ok {
458
470
l.Error("failed to get issue")
459
-
rp.pages.Error404(w)
471
+
rp.pages.Error404(w, pages.ErrorPageParams{
472
+
LoggedInUser: user,
473
+
})
460
474
return
461
475
}
462
476
···
497
511
issue, ok := r.Context().Value("issue").(*models.Issue)
498
512
if !ok {
499
513
l.Error("failed to get issue")
500
-
rp.pages.Error404(w)
514
+
rp.pages.Error404(w, pages.ErrorPageParams{
515
+
LoggedInUser: user,
516
+
})
501
517
return
502
518
}
503
519
···
601
617
issue, ok := r.Context().Value("issue").(*models.Issue)
602
618
if !ok {
603
619
l.Error("failed to get issue")
604
-
rp.pages.Error404(w)
620
+
rp.pages.Error404(w, pages.ErrorPageParams{
621
+
LoggedInUser: user,
622
+
})
605
623
return
606
624
}
607
625
···
642
660
issue, ok := r.Context().Value("issue").(*models.Issue)
643
661
if !ok {
644
662
l.Error("failed to get issue")
645
-
rp.pages.Error404(w)
663
+
rp.pages.Error404(w, pages.ErrorPageParams{
664
+
LoggedInUser: user,
665
+
})
646
666
return
647
667
}
648
668
···
683
703
issue, ok := r.Context().Value("issue").(*models.Issue)
684
704
if !ok {
685
705
l.Error("failed to get issue")
686
-
rp.pages.Error404(w)
706
+
rp.pages.Error404(w, pages.ErrorPageParams{
707
+
LoggedInUser: user,
708
+
})
687
709
return
688
710
}
689
711
···
770
792
isOpen = true
771
793
}
772
794
773
-
page := pagination.FromContext(r.Context())
795
+
page, ok := r.Context().Value("page").(pagination.Page)
796
+
if !ok {
797
+
l.Error("failed to get page")
798
+
page = pagination.FirstPage()
799
+
}
774
800
775
801
user := rp.oauth.GetUser(r)
776
802
f, err := rp.repoResolver.Resolve(r)
···
802
828
)
803
829
if err != nil {
804
830
l.Error("failed to fetch labels", "err", err)
805
-
rp.pages.Error503(w)
831
+
rp.pages.Error503(w, pages.ErrorPageParams{
832
+
LoggedInUser: user,
833
+
})
806
834
return
807
835
}
808
836
+21
-7
appview/middleware/middleware.go
+21
-7
appview/middleware/middleware.go
···
105
105
}
106
106
}
107
107
108
-
ctx := pagination.IntoContext(r.Context(), page)
108
+
ctx := context.WithValue(r.Context(), "page", page)
109
109
next.ServeHTTP(w, r.WithContext(ctx))
110
110
})
111
111
}
···
191
191
if err != nil {
192
192
// invalid did or handle
193
193
log.Printf("failed to resolve did/handle '%s': %s\n", didOrHandle, err)
194
-
mw.pages.Error404(w)
194
+
mw.pages.Error404(w, pages.ErrorPageParams{})
195
195
return
196
196
}
197
197
···
206
206
return func(next http.Handler) http.Handler {
207
207
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
208
208
repoName := chi.URLParam(req, "repo")
209
+
user := mw.oauth.GetUser(req)
209
210
id, ok := req.Context().Value("resolvedId").(identity.Identity)
210
211
if !ok {
211
212
log.Println("malformed middleware")
···
220
221
)
221
222
if err != nil {
222
223
log.Println("failed to resolve repo", "err", err)
223
-
mw.pages.ErrorKnot404(w)
224
+
mw.pages.ErrorKnot404(w, pages.ErrorPageParams{
225
+
LoggedInUser: user,
226
+
})
224
227
return
225
228
}
226
229
···
235
238
return func(next http.Handler) http.Handler {
236
239
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
237
240
f, err := mw.repoResolver.Resolve(r)
241
+
user := mw.oauth.GetUser(r)
238
242
if err != nil {
239
243
log.Println("failed to fully resolve repo", err)
240
-
mw.pages.ErrorKnot404(w)
244
+
mw.pages.ErrorKnot404(w, pages.ErrorPageParams{
245
+
LoggedInUser: user,
246
+
})
241
247
return
242
248
}
243
249
···
282
288
func (mw Middleware) ResolveIssue(next http.Handler) http.Handler {
283
289
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
284
290
f, err := mw.repoResolver.Resolve(r)
291
+
user := mw.oauth.GetUser(r)
285
292
if err != nil {
286
293
log.Println("failed to fully resolve repo", err)
287
-
mw.pages.ErrorKnot404(w)
294
+
mw.pages.ErrorKnot404(w, pages.ErrorPageParams{
295
+
LoggedInUser: user,
296
+
})
288
297
return
289
298
}
290
299
···
292
301
issueId, err := strconv.Atoi(issueIdStr)
293
302
if err != nil {
294
303
log.Println("failed to fully resolve issue ID", err)
295
-
mw.pages.ErrorKnot404(w)
304
+
mw.pages.ErrorKnot404(w, pages.ErrorPageParams{
305
+
LoggedInUser: user,
306
+
})
296
307
return
297
308
}
298
309
···
326
337
return func(next http.Handler) http.Handler {
327
338
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
328
339
f, err := mw.repoResolver.Resolve(r)
340
+
user := mw.oauth.GetUser(r)
329
341
if err != nil {
330
342
log.Println("failed to fully resolve repo", err)
331
-
mw.pages.ErrorKnot404(w)
343
+
mw.pages.ErrorKnot404(w, pages.ErrorPageParams{
344
+
LoggedInUser: user,
345
+
})
332
346
return
333
347
}
334
348
+11
-3
appview/notifications/notifications.go
+11
-3
appview/notifications/notifications.go
···
49
49
l := n.logger.With("handler", "notificationsPage")
50
50
user := n.oauth.GetUser(r)
51
51
52
-
page := pagination.FromContext(r.Context())
52
+
page, ok := r.Context().Value("page").(pagination.Page)
53
+
if !ok {
54
+
l.Error("failed to get page")
55
+
page = pagination.FirstPage()
56
+
}
53
57
54
58
total, err := db.CountNotifications(
55
59
n.db,
···
57
61
)
58
62
if err != nil {
59
63
l.Error("failed to get total notifications", "err", err)
60
-
n.pages.Error500(w)
64
+
n.pages.Error500(w, pages.ErrorPageParams{
65
+
LoggedInUser: user,
66
+
})
61
67
return
62
68
}
63
69
···
68
74
)
69
75
if err != nil {
70
76
l.Error("failed to get notifications", "err", err)
71
-
n.pages.Error500(w)
77
+
n.pages.Error500(w, pages.ErrorPageParams{
78
+
LoggedInUser: user,
79
+
})
72
80
return
73
81
}
74
82
+2
-13
appview/oauth/handler.go
+2
-13
appview/oauth/handler.go
···
4
4
"bytes"
5
5
"context"
6
6
"encoding/json"
7
-
"errors"
8
7
"fmt"
9
8
"net/http"
10
9
"slices"
11
10
"time"
12
11
13
-
"github.com/bluesky-social/indigo/atproto/auth/oauth"
14
12
"github.com/go-chi/chi/v5"
15
13
"github.com/lestrrat-go/jwx/v2/jwk"
16
14
"github.com/posthog/posthog-go"
···
60
58
61
59
func (o *OAuth) callback(w http.ResponseWriter, r *http.Request) {
62
60
ctx := r.Context()
63
-
l := o.Logger.With("query", r.URL.Query())
64
61
65
62
sessData, err := o.ClientApp.ProcessCallback(ctx, r.URL.Query())
66
63
if err != nil {
67
-
var callbackErr *oauth.AuthRequestCallbackError
68
-
if errors.As(err, &callbackErr) {
69
-
l.Debug("callback error", "err", callbackErr)
70
-
http.Redirect(w, r, fmt.Sprintf("/login?error=%s", callbackErr.ErrorCode), http.StatusFound)
71
-
return
72
-
}
73
-
l.Error("failed to process callback", "err", err)
74
-
http.Redirect(w, r, "/login?error=oauth", http.StatusFound)
64
+
http.Error(w, err.Error(), http.StatusInternalServerError)
75
65
return
76
66
}
77
67
78
68
if err := o.SaveSession(w, r, sessData); err != nil {
79
-
l.Error("failed to save session", "data", sessData, "err", err)
80
-
http.Redirect(w, r, "/login?error=session", http.StatusFound)
69
+
http.Error(w, err.Error(), http.StatusInternalServerError)
81
70
return
82
71
}
83
72
+1
-4
appview/oauth/oauth.go
+1
-4
appview/oauth/oauth.go
···
58
58
59
59
sessStore := sessions.NewCookieStore([]byte(config.Core.CookieSecret))
60
60
61
-
clientApp := oauth.NewClientApp(&oauthConfig, authStore)
62
-
clientApp.Dir = res.Directory()
63
-
64
61
return &OAuth{
65
-
ClientApp: clientApp,
62
+
ClientApp: oauth.NewClientApp(&oauthConfig, authStore),
66
63
Config: config,
67
64
SessStore: sessStore,
68
65
JwksUri: jwksUri,
+2
-3
appview/pages/funcmap.go
+2
-3
appview/pages/funcmap.go
···
297
297
},
298
298
299
299
"normalizeForHtmlId": func(s string) string {
300
-
normalized := strings.ReplaceAll(s, ":", "_")
301
-
normalized = strings.ReplaceAll(normalized, ".", "_")
302
-
return normalized
300
+
// TODO: extend this to handle other cases?
301
+
return strings.ReplaceAll(s, ":", "_")
303
302
},
304
303
"sshFingerprint": func(pubKey string) string {
305
304
fp, err := crypto.SSHFingerprint(pubKey)
+12
-9
appview/pages/pages.go
+12
-9
appview/pages/pages.go
···
221
221
222
222
type LoginParams struct {
223
223
ReturnUrl string
224
-
ErrorCode string
225
224
}
226
225
227
226
func (p *Pages) Login(w io.Writer, params LoginParams) error {
···
1382
1381
Active string
1383
1382
}
1384
1383
1384
+
type ErrorPageParams struct {
1385
+
LoggedInUser *oauth.User
1386
+
}
1387
+
1385
1388
func (p *Pages) Workflow(w io.Writer, params WorkflowParams) error {
1386
1389
params.Active = "pipelines"
1387
1390
return p.executeRepo("repo/pipelines/workflow", w, params)
···
1519
1522
return hex.EncodeToString(hasher.Sum(nil))[:8] // Use first 8 chars of hash
1520
1523
}
1521
1524
1522
-
func (p *Pages) Error500(w io.Writer) error {
1523
-
return p.execute("errors/500", w, nil)
1525
+
func (p *Pages) Error500(w io.Writer, params ErrorPageParams) error {
1526
+
return p.execute("errors/500", w, params)
1524
1527
}
1525
1528
1526
-
func (p *Pages) Error404(w io.Writer) error {
1527
-
return p.execute("errors/404", w, nil)
1529
+
func (p *Pages) Error404(w io.Writer, params ErrorPageParams) error {
1530
+
return p.execute("errors/404", w, params)
1528
1531
}
1529
1532
1530
-
func (p *Pages) ErrorKnot404(w io.Writer) error {
1531
-
return p.execute("errors/knot404", w, nil)
1533
+
func (p *Pages) ErrorKnot404(w io.Writer, params ErrorPageParams) error {
1534
+
return p.execute("errors/knot404", w, params)
1532
1535
}
1533
1536
1534
-
func (p *Pages) Error503(w io.Writer) error {
1535
-
return p.execute("errors/503", w, nil)
1537
+
func (p *Pages) Error503(w io.Writer, params ErrorPageParams) error {
1538
+
return p.execute("errors/503", w, params)
1536
1539
}
+1
-1
appview/pages/templates/strings/string.html
+1
-1
appview/pages/templates/strings/string.html
···
47
47
</span>
48
48
</section>
49
49
<section class="bg-white dark:bg-gray-800 px-6 py-4 rounded relative w-full dark:text-white">
50
-
<div class="flex flex-col md:flex-row md:justify-between md:items-center text-gray-500 dark:text-gray-400 text-sm md:text-base pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700">
50
+
<div class="flex justify-between items-center text-gray-500 dark:text-gray-400 text-sm md:text-base pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700">
51
51
<span>
52
52
{{ .String.Filename }}
53
53
<span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
+1
-1
appview/pages/templates/user/fragments/followCard.html
+1
-1
appview/pages/templates/user/fragments/followCard.html
···
3
3
<div class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700 rounded-sm">
4
4
<div class="py-4 px-6 drop-shadow-sm rounded bg-white dark:bg-gray-800 flex items-center gap-4">
5
5
<div class="flex-shrink-0 max-h-full w-24 h-24">
6
-
<img class="object-cover rounded-full p-2" src="{{ fullAvatar $userIdent }}" alt="{{ $userIdent }}" />
6
+
<img class="object-cover rounded-full p-2" src="{{ fullAvatar $userIdent }}" />
7
7
</div>
8
8
9
9
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-2 w-full">
+2
-20
appview/pages/templates/user/login.html
+2
-20
appview/pages/templates/user/login.html
···
13
13
<title>login · tangled</title>
14
14
</head>
15
15
<body class="flex items-center justify-center min-h-screen">
16
-
<main class="max-w-md px-7 mt-4">
16
+
<main class="max-w-md px-6 -mt-4">
17
17
<h1 class="flex place-content-center text-3xl font-semibold italic dark:text-white" >
18
18
{{ template "fragments/logotype" }}
19
19
</h1>
···
21
21
tightly-knit social coding.
22
22
</h2>
23
23
<form
24
-
class="mt-4"
24
+
class="mt-4 max-w-sm mx-auto"
25
25
hx-post="/login"
26
26
hx-swap="none"
27
27
hx-disabled-elt="#login-button"
···
56
56
<span>login</span>
57
57
</button>
58
58
</form>
59
-
{{ if .ErrorCode }}
60
-
<div class="flex gap-2 my-2 bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-3 py-2 text-red-500 dark:text-red-300">
61
-
<span class="py-1">{{ i "circle-alert" "w-4 h-4" }}</span>
62
-
<div>
63
-
<h5 class="font-medium">Login error</h5>
64
-
<p class="text-sm">
65
-
{{ if eq .ErrorCode "access_denied" }}
66
-
You have not authorized the app.
67
-
{{ else if eq .ErrorCode "session" }}
68
-
Server failed to create user session.
69
-
{{ else }}
70
-
Internal Server error.
71
-
{{ end }}
72
-
Please try again.
73
-
</p>
74
-
</div>
75
-
</div>
76
-
{{ end }}
77
59
<p class="text-sm text-gray-500">
78
60
Don't have an account? <a href="/signup" class="underline">Create an account</a> on Tangled now!
79
61
</p>
-23
appview/pagination/page.go
-23
appview/pagination/page.go
···
1
1
package pagination
2
2
3
-
import "context"
4
-
5
3
type Page struct {
6
4
Offset int // where to start from
7
5
Limit int // number of items in a page
···
12
10
Offset: 0,
13
11
Limit: 30,
14
12
}
15
-
}
16
-
17
-
type ctxKey struct{}
18
-
19
-
func IntoContext(ctx context.Context, page Page) context.Context {
20
-
return context.WithValue(ctx, ctxKey{}, page)
21
-
}
22
-
23
-
func FromContext(ctx context.Context) Page {
24
-
if ctx == nil {
25
-
return FirstPage()
26
-
}
27
-
v := ctx.Value(ctxKey{})
28
-
if v == nil {
29
-
return FirstPage()
30
-
}
31
-
page, ok := v.(Page)
32
-
if !ok {
33
-
return FirstPage()
34
-
}
35
-
return page
36
13
}
37
14
38
15
func (p Page) Previous() Page {
+30
-10
appview/pulls/pulls.go
+30
-10
appview/pulls/pulls.go
···
205
205
)
206
206
if err != nil {
207
207
log.Println("failed to fetch labels", err)
208
-
s.pages.Error503(w)
208
+
s.pages.Error503(w, pages.ErrorPageParams{
209
+
LoggedInUser: user,
210
+
})
209
211
return
210
212
}
211
213
···
636
638
)
637
639
if err != nil {
638
640
log.Println("failed to fetch labels", err)
639
-
s.pages.Error503(w)
641
+
s.pages.Error503(w, pages.ErrorPageParams{
642
+
LoggedInUser: user,
643
+
})
640
644
return
641
645
}
642
646
···
785
789
if err != nil {
786
790
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
787
791
log.Println("failed to call XRPC repo.branches", xrpcerr)
788
-
s.pages.Error503(w)
792
+
s.pages.Error503(w, pages.ErrorPageParams{
793
+
LoggedInUser: user,
794
+
})
789
795
return
790
796
}
791
797
log.Println("failed to fetch branches", err)
···
795
801
var result types.RepoBranchesResponse
796
802
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
797
803
log.Println("failed to decode XRPC response", err)
798
-
s.pages.Error503(w)
804
+
s.pages.Error503(w, pages.ErrorPageParams{
805
+
LoggedInUser: user,
806
+
})
799
807
return
800
808
}
801
809
···
1392
1400
if err != nil {
1393
1401
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1394
1402
log.Println("failed to call XRPC repo.branches", xrpcerr)
1395
-
s.pages.Error503(w)
1403
+
s.pages.Error503(w, pages.ErrorPageParams{
1404
+
LoggedInUser: user,
1405
+
})
1396
1406
return
1397
1407
}
1398
1408
log.Println("failed to fetch branches", err)
···
1402
1412
var result types.RepoBranchesResponse
1403
1413
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
1404
1414
log.Println("failed to decode XRPC response", err)
1405
-
s.pages.Error503(w)
1415
+
s.pages.Error503(w, pages.ErrorPageParams{
1416
+
LoggedInUser: user,
1417
+
})
1406
1418
return
1407
1419
}
1408
1420
···
1484
1496
if err != nil {
1485
1497
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1486
1498
log.Println("failed to call XRPC repo.branches for source", xrpcerr)
1487
-
s.pages.Error503(w)
1499
+
s.pages.Error503(w, pages.ErrorPageParams{
1500
+
LoggedInUser: user,
1501
+
})
1488
1502
return
1489
1503
}
1490
1504
log.Println("failed to fetch source branches", err)
···
1495
1509
var sourceBranches types.RepoBranchesResponse
1496
1510
if err := json.Unmarshal(sourceXrpcBytes, &sourceBranches); err != nil {
1497
1511
log.Println("failed to decode source branches XRPC response", err)
1498
-
s.pages.Error503(w)
1512
+
s.pages.Error503(w, pages.ErrorPageParams{
1513
+
LoggedInUser: user,
1514
+
})
1499
1515
return
1500
1516
}
1501
1517
···
1513
1529
if err != nil {
1514
1530
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1515
1531
log.Println("failed to call XRPC repo.branches for target", xrpcerr)
1516
-
s.pages.Error503(w)
1532
+
s.pages.Error503(w, pages.ErrorPageParams{
1533
+
LoggedInUser: user,
1534
+
})
1517
1535
return
1518
1536
}
1519
1537
log.Println("failed to fetch target branches", err)
···
1524
1542
var targetBranches types.RepoBranchesResponse
1525
1543
if err := json.Unmarshal(targetXrpcBytes, &targetBranches); err != nil {
1526
1544
log.Println("failed to decode target branches XRPC response", err)
1527
-
s.pages.Error503(w)
1545
+
s.pages.Error503(w, pages.ErrorPageParams{
1546
+
LoggedInUser: user,
1547
+
})
1528
1548
return
1529
1549
}
1530
1550
+8
-2
appview/repo/feed.go
+8
-2
appview/repo/feed.go
···
10
10
11
11
"tangled.org/core/appview/db"
12
12
"tangled.org/core/appview/models"
13
+
"tangled.org/core/appview/pages"
13
14
"tangled.org/core/appview/pagination"
14
15
"tangled.org/core/appview/reporesolver"
15
16
···
152
153
log.Println("failed to fully resolve repo:", err)
153
154
return
154
155
}
156
+
user := rp.oauth.GetUser(r)
155
157
156
158
feed, err := rp.getRepoFeed(r.Context(), f)
157
159
if err != nil {
158
160
log.Println("failed to get repo feed:", err)
159
-
rp.pages.Error500(w)
161
+
rp.pages.Error500(w, pages.ErrorPageParams{
162
+
LoggedInUser: user,
163
+
})
160
164
return
161
165
}
162
166
163
167
atom, err := feed.ToAtom()
164
168
if err != nil {
165
-
rp.pages.Error500(w)
169
+
rp.pages.Error500(w, pages.ErrorPageParams{
170
+
LoggedInUser: user,
171
+
})
166
172
return
167
173
}
168
174
+3
-1
appview/repo/index.go
+3
-1
appview/repo/index.go
+83
-34
appview/repo/repo.go
+83
-34
appview/repo/repo.go
···
90
90
91
91
func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) {
92
92
l := rp.logger.With("handler", "DownloadArchive")
93
+
user := rp.oauth.GetUser(r)
93
94
94
95
ref := chi.URLParam(r, "ref")
95
96
ref, _ = url.PathUnescape(ref)
···
113
114
archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", ref, repo)
114
115
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
115
116
l.Error("failed to call XRPC repo.archive", "err", xrpcerr)
116
-
rp.pages.Error503(w)
117
+
rp.pages.Error503(w, pages.ErrorPageParams{
118
+
LoggedInUser: user,
119
+
})
117
120
return
118
121
}
119
122
···
130
133
131
134
func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) {
132
135
l := rp.logger.With("handler", "RepoLog")
136
+
user := rp.oauth.GetUser(r)
133
137
134
138
f, err := rp.repoResolver.Resolve(r)
135
139
if err != nil {
···
169
173
xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo)
170
174
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
171
175
l.Error("failed to call XRPC repo.log", "err", xrpcerr)
172
-
rp.pages.Error503(w)
176
+
rp.pages.Error503(w, pages.ErrorPageParams{
177
+
LoggedInUser: user,
178
+
})
173
179
return
174
180
}
175
181
176
182
var xrpcResp types.RepoLogResponse
177
183
if err := json.Unmarshal(xrpcBytes, &xrpcResp); err != nil {
178
184
l.Error("failed to decode XRPC response", "err", err)
179
-
rp.pages.Error503(w)
185
+
rp.pages.Error503(w, pages.ErrorPageParams{
186
+
LoggedInUser: user,
187
+
})
180
188
return
181
189
}
182
190
183
191
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
184
192
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
185
193
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
186
-
rp.pages.Error503(w)
194
+
rp.pages.Error503(w, pages.ErrorPageParams{
195
+
LoggedInUser: user,
196
+
})
187
197
return
188
198
}
189
199
···
204
214
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
205
215
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
206
216
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
207
-
rp.pages.Error503(w)
217
+
rp.pages.Error503(w, pages.ErrorPageParams{
218
+
LoggedInUser: user,
219
+
})
208
220
return
209
221
}
210
222
···
216
228
}
217
229
}
218
230
}
219
-
220
-
user := rp.oauth.GetUser(r)
221
231
222
232
emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true)
223
233
if err != nil {
···
353
363
354
364
func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) {
355
365
l := rp.logger.With("handler", "RepoCommit")
366
+
user := rp.oauth.GetUser(r)
356
367
357
368
f, err := rp.repoResolver.Resolve(r)
358
369
if err != nil {
···
368
379
}
369
380
370
381
if !plumbing.IsHash(ref) {
371
-
rp.pages.Error404(w)
382
+
rp.pages.Error404(w, pages.ErrorPageParams{
383
+
LoggedInUser: user,
384
+
})
372
385
return
373
386
}
374
387
···
385
398
xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo)
386
399
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
387
400
l.Error("failed to call XRPC repo.diff", "err", xrpcerr)
388
-
rp.pages.Error503(w)
401
+
rp.pages.Error503(w, pages.ErrorPageParams{
402
+
LoggedInUser: user,
403
+
})
389
404
return
390
405
}
391
406
392
407
var result types.RepoCommitResponse
393
408
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
394
409
l.Error("failed to decode XRPC response", "err", err)
395
-
rp.pages.Error503(w)
410
+
rp.pages.Error503(w, pages.ErrorPageParams{
411
+
LoggedInUser: user,
412
+
})
396
413
return
397
414
}
398
415
···
406
423
l.Error("failed to GetVerifiedCommits", "err", err)
407
424
}
408
425
409
-
user := rp.oauth.GetUser(r)
410
426
repoInfo := f.RepoInfo(user)
411
427
pipelines, err := getPipelineStatuses(rp.db, repoInfo, []string{result.Diff.Commit.This})
412
428
if err != nil {
···
431
447
432
448
func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) {
433
449
l := rp.logger.With("handler", "RepoTree")
450
+
user := rp.oauth.GetUser(r)
434
451
435
452
f, err := rp.repoResolver.Resolve(r)
436
453
if err != nil {
···
460
477
xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo)
461
478
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
462
479
l.Error("failed to call XRPC repo.tree", "err", xrpcerr)
463
-
rp.pages.Error503(w)
480
+
rp.pages.Error503(w, pages.ErrorPageParams{
481
+
LoggedInUser: user,
482
+
})
464
483
return
465
484
}
466
485
···
511
530
http.Redirect(w, r, redirectTo, http.StatusFound)
512
531
return
513
532
}
514
-
515
-
user := rp.oauth.GetUser(r)
516
533
517
534
var breadcrumbs [][]string
518
535
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), url.PathEscape(ref))})
···
535
552
536
553
func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) {
537
554
l := rp.logger.With("handler", "RepoTags")
555
+
user := rp.oauth.GetUser(r)
538
556
539
557
f, err := rp.repoResolver.Resolve(r)
540
558
if err != nil {
···
555
573
xrpcBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
556
574
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
557
575
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
558
-
rp.pages.Error503(w)
576
+
rp.pages.Error503(w, pages.ErrorPageParams{
577
+
LoggedInUser: user,
578
+
})
559
579
return
560
580
}
561
581
562
582
var result types.RepoTagsResponse
563
583
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
564
584
l.Error("failed to decode XRPC response", "err", err)
565
-
rp.pages.Error503(w)
585
+
rp.pages.Error503(w, pages.ErrorPageParams{
586
+
LoggedInUser: user,
587
+
})
566
588
return
567
589
}
568
590
···
594
616
}
595
617
}
596
618
597
-
user := rp.oauth.GetUser(r)
598
619
rp.pages.RepoTags(w, pages.RepoTagsParams{
599
620
LoggedInUser: user,
600
621
RepoInfo: f.RepoInfo(user),
···
606
627
607
628
func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) {
608
629
l := rp.logger.With("handler", "RepoBranches")
630
+
user := rp.oauth.GetUser(r)
609
631
610
632
f, err := rp.repoResolver.Resolve(r)
611
633
if err != nil {
···
626
648
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
627
649
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
628
650
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
629
-
rp.pages.Error503(w)
651
+
rp.pages.Error503(w, pages.ErrorPageParams{
652
+
LoggedInUser: user,
653
+
})
630
654
return
631
655
}
632
656
633
657
var result types.RepoBranchesResponse
634
658
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
635
659
l.Error("failed to decode XRPC response", "err", err)
636
-
rp.pages.Error503(w)
660
+
rp.pages.Error503(w, pages.ErrorPageParams{
661
+
LoggedInUser: user,
662
+
})
637
663
return
638
664
}
639
665
640
666
sortBranches(result.Branches)
641
667
642
-
user := rp.oauth.GetUser(r)
643
668
rp.pages.RepoBranches(w, pages.RepoBranchesParams{
644
669
LoggedInUser: user,
645
670
RepoInfo: f.RepoInfo(user),
···
698
723
699
724
func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) {
700
725
l := rp.logger.With("handler", "RepoBlob")
726
+
user := rp.oauth.GetUser(r)
701
727
702
728
f, err := rp.repoResolver.Resolve(r)
703
729
if err != nil {
···
724
750
resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo)
725
751
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
726
752
l.Error("failed to call XRPC repo.blob", "err", xrpcerr)
727
-
rp.pages.Error503(w)
753
+
rp.pages.Error503(w, pages.ErrorPageParams{
754
+
LoggedInUser: user,
755
+
})
728
756
return
729
757
}
730
758
···
796
824
sizeHint = uint64(len(resp.Content))
797
825
}
798
826
799
-
user := rp.oauth.GetUser(r)
800
-
801
827
// Determine if content is binary (dereference pointer)
802
828
isBinary := false
803
829
if resp.IsBinary != nil {
···
824
850
825
851
func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) {
826
852
l := rp.logger.With("handler", "RepoBlobRaw")
853
+
user := rp.oauth.GetUser(r)
827
854
828
855
f, err := rp.repoResolver.Resolve(r)
829
856
if err != nil {
···
872
899
resp, err := client.Do(req)
873
900
if err != nil {
874
901
l.Error("failed to reach knotserver", "err", err)
875
-
rp.pages.Error503(w)
902
+
rp.pages.Error503(w, pages.ErrorPageParams{
903
+
LoggedInUser: user,
904
+
})
876
905
return
877
906
}
878
907
defer resp.Body.Close()
···
1963
1992
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1964
1993
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1965
1994
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
1966
-
rp.pages.Error503(w)
1995
+
rp.pages.Error503(w, pages.ErrorPageParams{
1996
+
LoggedInUser: user,
1997
+
})
1967
1998
return
1968
1999
}
1969
2000
1970
2001
var result types.RepoBranchesResponse
1971
2002
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
1972
2003
l.Error("failed to decode XRPC response", "err", err)
1973
-
rp.pages.Error503(w)
2004
+
rp.pages.Error503(w, pages.ErrorPageParams{
2005
+
LoggedInUser: user,
2006
+
})
1974
2007
return
1975
2008
}
1976
2009
1977
2010
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs()))
1978
2011
if err != nil {
1979
2012
l.Error("failed to fetch labels", "err", err)
1980
-
rp.pages.Error503(w)
2013
+
rp.pages.Error503(w, pages.ErrorPageParams{
2014
+
LoggedInUser: user,
2015
+
})
1981
2016
return
1982
2017
}
1983
2018
1984
2019
labels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Repo.Labels))
1985
2020
if err != nil {
1986
2021
l.Error("failed to fetch labels", "err", err)
1987
-
rp.pages.Error503(w)
2022
+
rp.pages.Error503(w, pages.ErrorPageParams{
2023
+
LoggedInUser: user,
2024
+
})
1988
2025
return
1989
2026
}
1990
2027
// remove default labels from the labels list, if present
···
2418
2455
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
2419
2456
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2420
2457
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
2421
-
rp.pages.Error503(w)
2458
+
rp.pages.Error503(w, pages.ErrorPageParams{
2459
+
LoggedInUser: user,
2460
+
})
2422
2461
return
2423
2462
}
2424
2463
···
2455
2494
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
2456
2495
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2457
2496
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
2458
-
rp.pages.Error503(w)
2497
+
rp.pages.Error503(w, pages.ErrorPageParams{
2498
+
LoggedInUser: user,
2499
+
})
2459
2500
return
2460
2501
}
2461
2502
···
2512
2553
2513
2554
if base == "" || head == "" {
2514
2555
l.Error("invalid comparison")
2515
-
rp.pages.Error404(w)
2556
+
rp.pages.Error404(w, pages.ErrorPageParams{
2557
+
LoggedInUser: user,
2558
+
})
2516
2559
return
2517
2560
}
2518
2561
···
2530
2573
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
2531
2574
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2532
2575
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
2533
-
rp.pages.Error503(w)
2576
+
rp.pages.Error503(w, pages.ErrorPageParams{
2577
+
LoggedInUser: user,
2578
+
})
2534
2579
return
2535
2580
}
2536
2581
···
2544
2589
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
2545
2590
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2546
2591
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
2547
-
rp.pages.Error503(w)
2592
+
rp.pages.Error503(w, pages.ErrorPageParams{
2593
+
LoggedInUser: user,
2594
+
})
2548
2595
return
2549
2596
}
2550
2597
···
2558
2605
compareBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, base, head)
2559
2606
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2560
2607
l.Error("failed to call XRPC repo.compare", "err", xrpcerr)
2561
-
rp.pages.Error503(w)
2608
+
rp.pages.Error503(w, pages.ErrorPageParams{
2609
+
LoggedInUser: user,
2610
+
})
2562
2611
return
2563
2612
}
2564
2613
-1
appview/state/follow.go
-1
appview/state/follow.go
+10
-3
appview/state/gfi.go
+10
-3
appview/state/gfi.go
···
18
18
func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) {
19
19
user := s.oauth.GetUser(r)
20
20
21
-
page := pagination.FromContext(r.Context())
21
+
page, ok := r.Context().Value("page").(pagination.Page)
22
+
if !ok {
23
+
page = pagination.FirstPage()
24
+
}
22
25
23
26
goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
24
27
25
28
repoLabels, err := db.GetRepoLabels(s.db, db.FilterEq("label_at", goodFirstIssueLabel))
26
29
if err != nil {
27
30
log.Println("failed to get repo labels", err)
28
-
s.pages.Error503(w)
31
+
s.pages.Error503(w, pages.ErrorPageParams{
32
+
LoggedInUser: user,
33
+
})
29
34
return
30
35
}
31
36
···
54
59
)
55
60
if err != nil {
56
61
log.Println("failed to get issues", err)
57
-
s.pages.Error503(w)
62
+
s.pages.Error503(w, pages.ErrorPageParams{
63
+
LoggedInUser: user,
64
+
})
58
65
return
59
66
}
60
67
-2
appview/state/login.go
-2
appview/state/login.go
···
14
14
switch r.Method {
15
15
case http.MethodGet:
16
16
returnURL := r.URL.Query().Get("return_url")
17
-
errorCode := r.URL.Query().Get("error")
18
17
s.pages.Login(w, pages.LoginParams{
19
18
ReturnUrl: returnURL,
20
-
ErrorCode: errorCode,
21
19
})
22
20
case http.MethodPost:
23
21
handle := r.FormValue("handle")
+36
-10
appview/state/profile.go
+36
-10
appview/state/profile.go
···
112
112
113
113
func (s *State) profileOverview(w http.ResponseWriter, r *http.Request) {
114
114
l := s.logger.With("handler", "profileHomePage")
115
+
user := s.oauth.GetUser(r)
115
116
116
117
profile, err := s.profile(r)
117
118
if err != nil {
118
119
l.Error("failed to build profile card", "err", err)
119
-
s.pages.Error500(w)
120
+
s.pages.Error500(w, pages.ErrorPageParams{
121
+
LoggedInUser: user,
122
+
})
120
123
return
121
124
}
122
125
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
···
173
176
174
177
func (s *State) reposPage(w http.ResponseWriter, r *http.Request) {
175
178
l := s.logger.With("handler", "reposPage")
179
+
user := s.oauth.GetUser(r)
176
180
177
181
profile, err := s.profile(r)
178
182
if err != nil {
179
183
l.Error("failed to build profile card", "err", err)
180
-
s.pages.Error500(w)
184
+
s.pages.Error500(w, pages.ErrorPageParams{
185
+
LoggedInUser: user,
186
+
})
181
187
return
182
188
}
183
189
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
···
189
195
)
190
196
if err != nil {
191
197
l.Error("failed to get repos", "err", err)
192
-
s.pages.Error500(w)
198
+
s.pages.Error500(w, pages.ErrorPageParams{
199
+
LoggedInUser: user,
200
+
})
193
201
return
194
202
}
195
203
···
202
210
203
211
func (s *State) starredPage(w http.ResponseWriter, r *http.Request) {
204
212
l := s.logger.With("handler", "starredPage")
213
+
user := s.oauth.GetUser(r)
205
214
206
215
profile, err := s.profile(r)
207
216
if err != nil {
208
217
l.Error("failed to build profile card", "err", err)
209
-
s.pages.Error500(w)
218
+
s.pages.Error500(w, pages.ErrorPageParams{
219
+
LoggedInUser: user,
220
+
})
210
221
return
211
222
}
212
223
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
···
214
225
stars, err := db.GetStars(s.db, 0, db.FilterEq("starred_by_did", profile.UserDid))
215
226
if err != nil {
216
227
l.Error("failed to get stars", "err", err)
217
-
s.pages.Error500(w)
228
+
s.pages.Error500(w, pages.ErrorPageParams{
229
+
LoggedInUser: user,
230
+
})
218
231
return
219
232
}
220
233
var repos []models.Repo
···
233
246
234
247
func (s *State) stringsPage(w http.ResponseWriter, r *http.Request) {
235
248
l := s.logger.With("handler", "stringsPage")
249
+
user := s.oauth.GetUser(r)
236
250
237
251
profile, err := s.profile(r)
238
252
if err != nil {
239
253
l.Error("failed to build profile card", "err", err)
240
-
s.pages.Error500(w)
254
+
s.pages.Error500(w, pages.ErrorPageParams{
255
+
LoggedInUser: user,
256
+
})
241
257
return
242
258
}
243
259
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
···
245
261
strings, err := db.GetStrings(s.db, 0, db.FilterEq("did", profile.UserDid))
246
262
if err != nil {
247
263
l.Error("failed to get strings", "err", err)
248
-
s.pages.Error500(w)
264
+
s.pages.Error500(w, pages.ErrorPageParams{
265
+
LoggedInUser: user,
266
+
})
249
267
return
250
268
}
251
269
···
380
398
381
399
func (s *State) AtomFeedPage(w http.ResponseWriter, r *http.Request) {
382
400
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
401
+
user := s.oauth.GetUser(r)
402
+
383
403
if !ok {
384
-
s.pages.Error404(w)
404
+
s.pages.Error404(w, pages.ErrorPageParams{
405
+
LoggedInUser: user,
406
+
})
385
407
return
386
408
}
387
409
388
410
feed, err := s.getProfileFeed(r.Context(), &ident)
389
411
if err != nil {
390
-
s.pages.Error500(w)
412
+
s.pages.Error500(w, pages.ErrorPageParams{
413
+
LoggedInUser: user,
414
+
})
391
415
return
392
416
}
393
417
···
397
421
398
422
atom, err := feed.ToAtom()
399
423
if err != nil {
400
-
s.pages.Error500(w)
424
+
s.pages.Error500(w, pages.ErrorPageParams{
425
+
LoggedInUser: user,
426
+
})
401
427
return
402
428
}
403
429
+3
-2
appview/state/router.go
+3
-2
appview/state/router.go
···
10
10
"tangled.org/core/appview/labels"
11
11
"tangled.org/core/appview/middleware"
12
12
"tangled.org/core/appview/notifications"
13
+
"tangled.org/core/appview/pages"
13
14
"tangled.org/core/appview/pipelines"
14
15
"tangled.org/core/appview/pulls"
15
16
"tangled.org/core/appview/repo"
···
103
104
})
104
105
105
106
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
106
-
s.pages.Error404(w)
107
+
s.pages.Error404(w, pages.ErrorPageParams{})
107
108
})
108
109
109
110
return r
···
174
175
r.Get("/brand", s.Brand)
175
176
176
177
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
177
-
s.pages.Error404(w)
178
+
s.pages.Error404(w, pages.ErrorPageParams{})
178
179
})
179
180
return r
180
181
}
+4
-1
appview/strings/strings.go
+4
-1
appview/strings/strings.go
···
88
88
89
89
func (s *Strings) contents(w http.ResponseWriter, r *http.Request) {
90
90
l := s.Logger.With("handler", "contents")
91
+
user := s.OAuth.GetUser(r)
91
92
92
93
id, ok := r.Context().Value("resolvedId").(identity.Identity)
93
94
if !ok {
···
118
119
}
119
120
if len(strings) < 1 {
120
121
l.Error("string not found")
121
-
s.Pages.Error404(w)
122
+
s.Pages.Error404(w, pages.ErrorPageParams{
123
+
LoggedInUser: user,
124
+
})
122
125
return
123
126
}
124
127
if len(strings) != 1 {
+1
-1
spindle/engines/nixery/engine.go
+1
-1
spindle/engines/nixery/engine.go
···
222
222
},
223
223
ReadonlyRootfs: false,
224
224
CapDrop: []string{"ALL"},
225
-
CapAdd: []string{"CAP_DAC_OVERRIDE", "CAP_CHOWN", "CAP_FOWNER", "CAP_SETUID", "CAP_SETGID"},
225
+
CapAdd: []string{"CAP_DAC_OVERRIDE"},
226
226
SecurityOpt: []string{"no-new-privileges"},
227
227
ExtraHosts: []string{"host.docker.internal:host-gateway"},
228
228
}, nil, nil, "")