Added error page template

This commit is contained in:
Maxim Lebedev 2022-01-31 21:15:38 +05:00
parent 6e765670a7
commit 9ef9e16625
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
11 changed files with 563 additions and 187 deletions

View File

@ -44,31 +44,36 @@ var messageKeyToIndex = map[string]int{
"Authorize application": 1,
"Choose your scopes": 2,
"Deny": 3,
"Recipient": 7,
"Resource": 8,
"Send": 9,
"Sign In": 5,
"TicketAuth": 6,
"Error": 5,
"How do I fix it?": 6,
"Recipient": 9,
"Resource": 10,
"Send": 11,
"Sign In": 7,
"TicketAuth": 8,
}
var enIndex = []uint32{ // 11 elements
var enIndex = []uint32{ // 13 elements
0x00000000, 0x00000010, 0x00000026, 0x00000039,
0x0000003e, 0x00000044, 0x0000004c, 0x00000057,
0x00000061, 0x0000006a, 0x0000006f,
} // Size: 68 bytes
0x0000003e, 0x00000044, 0x0000004a, 0x0000005b,
0x00000063, 0x0000006e, 0x00000078, 0x00000081,
0x00000086,
} // Size: 76 bytes
const enData string = "" + // Size: 111 bytes
const enData string = "" + // Size: 134 bytes
"\x02Authorize %[1]s\x02Authorize application\x02Choose your scopes\x02De" +
"ny\x02Allow\x02Sign In\x02TicketAuth\x02Recipient\x02Resource\x02Send"
"ny\x02Allow\x02Error\x02How do I fix it?\x02Sign In\x02TicketAuth\x02Rec" +
"ipient\x02Resource\x02Send"
var ruIndex = []uint32{ // 11 elements
var ruIndex = []uint32{ // 13 elements
0x00000000, 0x0000001f, 0x0000004d, 0x0000008e,
0x0000009f, 0x000000b2, 0x000000bd, 0x000000bd,
0x000000bd, 0x000000bd, 0x000000bd,
} // Size: 68 bytes
0x0000009f, 0x000000b2, 0x000000b2, 0x000000b2,
0x000000bd, 0x000000bd, 0x000000bd, 0x000000bd,
0x000000bd,
} // Size: 76 bytes
const ruData string = "" + // Size: 189 bytes
"\x02Авторизовать %[1]s\x02Авторизовать приложение\x02Выбери предоставляе" +
"мые разрешения\x02Отказать\x02Разрешить\x02Войти"
// Total table size 436 bytes (0KiB); checksum: BBD74FCF
// Total table size 475 bytes (0KiB); checksum: F5D99818

View File

@ -1,6 +1,7 @@
package http
import (
"bytes"
"crypto/subtle"
"errors"
"path"
@ -159,36 +160,54 @@ func (h *RequestHandler) Register(r *router.Router) {
func (h *RequestHandler) handleRender(ctx *http.RequestCtx) {
req := new(AuthorizeRequest)
ctx.SetContentType(common.MIMETextHTMLCharsetUTF8)
tags, _, _ := language.ParseAcceptLanguage(string(ctx.Request.Header.Peek(http.HeaderAcceptLanguage)))
tag, _, _ := h.matcher.Match(tags...)
baseOf := web.BaseOf{
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
}
if err := req.bind(ctx); err != nil {
ctx.Error(err.Error(), http.StatusBadRequest)
ctx.SetStatusCode(http.StatusBadRequest)
web.WriteTemplate(ctx, &web.ErrorPage{
BaseOf: baseOf,
Error: err,
})
return
}
client, err := h.clients.Discovery(ctx, req.ClientID)
if err != nil {
ctx.Error(err.Error(), http.StatusBadRequest)
ctx.SetStatusCode(http.StatusBadRequest)
web.WriteTemplate(ctx, &web.ErrorPage{
BaseOf: baseOf,
Error: err,
})
return
}
if !client.ValidateRedirectURI(req.RedirectURI) {
ctx.Error("requested redirect_uri is not registered on client_id side", http.StatusBadRequest)
ctx.SetStatusCode(http.StatusBadRequest)
web.WriteTemplate(ctx, &web.ErrorPage{
BaseOf: baseOf,
Error: domain.NewError(
domain.ErrorCodeInvalidClient,
"requested redirect_uri is not registered on client_id side",
"",
),
})
return
}
csrf, _ := ctx.UserValue(middleware.DefaultCSRFConfig.ContextKey).([]byte)
tags, _, _ := language.ParseAcceptLanguage(string(ctx.Request.Header.Peek(http.HeaderAcceptLanguage)))
tag, _, _ := h.matcher.Match(tags...)
ctx.SetContentType(common.MIMETextHTMLCharsetUTF8)
web.WriteTemplate(ctx, &web.AuthorizePage{
BaseOf: web.BaseOf{
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
},
BaseOf: baseOf,
Client: client,
CodeChallenge: req.CodeChallenge,
CodeChallengeMethod: req.CodeChallengeMethod,
@ -298,8 +317,7 @@ func (r *AuthorizeRequest) bind(ctx *http.RequestCtx) error {
}
r.Scope = make(domain.Scopes, 0)
if err := parseScope(r.Scope, ctx.QueryArgs().Peek("scope")); err != nil {
if err := r.Scope.UnmarshalForm(ctx.QueryArgs().Peek("scope")); err != nil {
if errors.As(err, indieAuthError) {
return indieAuthError
}
@ -334,7 +352,17 @@ func (r *VerifyRequest) bind(ctx *http.RequestCtx) error {
}
r.Scope = make(domain.Scopes, 0)
parseScope(r.Scope, ctx.PostArgs().PeekMulti("scope[]")...)
if err := r.Scope.UnmarshalForm(bytes.Join(ctx.PostArgs().PeekMulti("scope[]"), []byte(" "))); err != nil {
if errors.As(err, indieAuthError) {
return indieAuthError
}
return domain.NewError(
domain.ErrorCodeInvalidScope,
err.Error(),
"https://indieweb.org/scope",
)
}
if r.ResponseType == domain.ResponseTypeID {
r.ResponseType = domain.ResponseTypeCode
@ -369,31 +397,3 @@ func (r *ExchangeRequest) bind(ctx *http.RequestCtx) error {
return nil
}
// TODO(toby3d): fix this in form pkg.
func parseScope(dst domain.Scopes, src ...[]byte) error {
if len(src) == 0 {
return nil
}
var scopes []string
if len(src) == 1 {
scopes = strings.Fields(string(src[0]))
}
for _, rawScope := range scopes {
scope, err := domain.ParseScope(string(rawScope))
if err != nil {
return domain.NewError(
domain.ErrorCodeInvalidScope,
err.Error(),
"https://indieweb.org/scope#IndieAuth_Scopes",
)
}
dst = append(dst, scope)
}
return nil
}

View File

@ -83,17 +83,16 @@ func (h *RequestHandler) handleRender(ctx *http.RequestCtx) {
tags, _, _ := language.ParseAcceptLanguage(string(ctx.Request.Header.Peek(http.HeaderAcceptLanguage)))
tag, _, _ := h.matcher.Match(tags...)
baseOf := web.BaseOf{
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
}
csrf, _ := ctx.UserValue("csrf").([]byte)
ctx.SetContentType(common.MIMETextHTMLCharsetUTF8)
web.WriteTemplate(ctx, &web.TicketPage{
BaseOf: web.BaseOf{
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
},
CSRF: csrf,
BaseOf: baseOf,
CSRF: csrf,
})
}

View File

@ -46,12 +46,54 @@
"translatorComment": "The name of the button to continue the application authorization process",
"fuzzy": true
},
{
"id": "Error",
"message": "Error",
"translation": "Error",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": "How do I fix it?",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Sign In",
"message": "Sign In",
"translation": "Sign In",
"translatorComment": "The name of the button in the site address entry form to start the login process",
"fuzzy": true
},
{
"id": "TicketAuth",
"message": "TicketAuth",
"translation": "TicketAuth",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Recipient",
"message": "Recipient",
"translation": "Recipient",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Resource",
"message": "Resource",
"translation": "Resource",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Send",
"message": "Send",
"translation": "Send",
"translatorComment": "Copied from source.",
"fuzzy": true
}
]
}

View File

@ -46,6 +46,20 @@
"translatorComment": "The name of the button to continue the application authorization process",
"fuzzy": true
},
{
"id": "Error",
"message": "Error",
"translation": "Error",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": "How do I fix it?",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Sign In",
"message": "Sign In",

View File

@ -39,11 +39,41 @@
"translation": "Разрешить",
"translatorComment": "Название кнопки продолжения процесса авторизациии приложения"
},
{
"id": "Error",
"message": "Error",
"translation": "Ошибка"
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": "Как исправить это?"
},
{
"id": "Sign In",
"message": "Sign In",
"translation": "Войти",
"translatorComment": "Название кнопки в форме ввода адреса сайта для начала процесса входа"
},
{
"id": "TicketAuth",
"message": "TicketAuth",
"translation": "TicketAuth"
},
{
"id": "Recipient",
"message": "Recipient",
"translation": "Получатель"
},
{
"id": "Resource",
"message": "Resource",
"translation": "Ресурс"
},
{
"id": "Send",
"message": "Send",
"translation": "Отправить"
}
]
}

View File

@ -39,6 +39,16 @@
"translation": "Разрешить",
"translatorComment": "Название кнопки продолжения процесса авторизациии приложения"
},
{
"id": "Error",
"message": "Error",
"translation": ""
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": ""
},
{
"id": "Sign In",
"message": "Sign In",

View File

@ -2,13 +2,14 @@
{% code type AuthorizePage struct {
BaseOf
CSRF []byte
Providers []*domain.Provider
Scope domain.Scopes
Client *domain.Client
RedirectURI *domain.URL
Me *domain.Me
RedirectURI *domain.URL
CodeChallengeMethod domain.CodeChallengeMethod
ResponseType domain.ResponseType
Scope domain.Scopes
CSRF []byte
CodeChallenge string
State string
} %}
@ -119,6 +120,25 @@
value="{%s p.Me.String() %}">
{% endif %}
{% if len(p.Providers) > 0 %}
<select
name="provider"
autocomplete
required>
{% for _, provider := range p.Providers %}
<option
value="{%s provider.UID %}"
{% if provider.UID == "mastodon" %}selected{% endif %}>
{%s provider.Name %}
</option>
{% endfor %}
</select>
{% else %}
<input type="hidden" name="provider" value="direct">
{% endif %}
<button
type="submit"
name="authorize"

View File

@ -23,91 +23,92 @@ var (
//line web/authorize.qtpl:3
type AuthorizePage struct {
BaseOf
CSRF []byte
Providers []*domain.Provider
Scope domain.Scopes
Client *domain.Client
RedirectURI *domain.URL
Me *domain.Me
RedirectURI *domain.URL
CodeChallengeMethod domain.CodeChallengeMethod
ResponseType domain.ResponseType
Scope domain.Scopes
CSRF []byte
CodeChallenge string
State string
}
//line web/authorize.qtpl:16
//line web/authorize.qtpl:17
func (p *AuthorizePage) StreamTitle(qw422016 *qt422016.Writer) {
//line web/authorize.qtpl:16
//line web/authorize.qtpl:17
qw422016.N().S(`
`)
//line web/authorize.qtpl:17
//line web/authorize.qtpl:18
if p.Client.GetName() == "" {
//line web/authorize.qtpl:17
//line web/authorize.qtpl:18
qw422016.N().S(`
`)
//line web/authorize.qtpl:18
//line web/authorize.qtpl:19
p.StreamT(qw422016, "Authorize %s", p.Client.GetName())
//line web/authorize.qtpl:18
//line web/authorize.qtpl:19
qw422016.N().S(`
`)
//line web/authorize.qtpl:19
//line web/authorize.qtpl:20
} else {
//line web/authorize.qtpl:19
//line web/authorize.qtpl:20
qw422016.N().S(`
`)
//line web/authorize.qtpl:20
//line web/authorize.qtpl:21
p.StreamT(qw422016, "Authorize application")
//line web/authorize.qtpl:20
//line web/authorize.qtpl:21
qw422016.N().S(`
`)
//line web/authorize.qtpl:21
//line web/authorize.qtpl:22
}
//line web/authorize.qtpl:21
//line web/authorize.qtpl:22
qw422016.N().S(`
`)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
}
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
func (p *AuthorizePage) WriteTitle(qq422016 qtio422016.Writer) {
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
qw422016 := qt422016.AcquireWriter(qq422016)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
p.StreamTitle(qw422016)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
qt422016.ReleaseWriter(qw422016)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
}
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
func (p *AuthorizePage) Title() string {
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
qb422016 := qt422016.AcquireByteBuffer()
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
p.WriteTitle(qb422016)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
qs422016 := string(qb422016.B)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
qt422016.ReleaseByteBuffer(qb422016)
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
return qs422016
//line web/authorize.qtpl:22
//line web/authorize.qtpl:23
}
//line web/authorize.qtpl:24
//line web/authorize.qtpl:25
func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
//line web/authorize.qtpl:24
//line web/authorize.qtpl:25
qw422016.N().S(`
<header>
`)
//line web/authorize.qtpl:26
//line web/authorize.qtpl:27
if p.Client.GetLogo() != nil {
//line web/authorize.qtpl:26
//line web/authorize.qtpl:27
qw422016.N().S(`
<img
alt="`)
//line web/authorize.qtpl:28
//line web/authorize.qtpl:29
qw422016.E().S(p.Client.GetName())
//line web/authorize.qtpl:28
//line web/authorize.qtpl:29
qw422016.N().S(`"
crossorigin="anonymous"
decoding="async"
@ -116,68 +117,68 @@ func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
src="`)
//line web/authorize.qtpl:35
//line web/authorize.qtpl:36
qw422016.E().S(p.Client.GetLogo().String())
//line web/authorize.qtpl:35
//line web/authorize.qtpl:36
qw422016.N().S(`"
width="140">
`)
//line web/authorize.qtpl:37
//line web/authorize.qtpl:38
}
//line web/authorize.qtpl:37
//line web/authorize.qtpl:38
qw422016.N().S(`
<h2>
`)
//line web/authorize.qtpl:40
//line web/authorize.qtpl:41
if p.Client.GetURL() != nil {
//line web/authorize.qtpl:40
//line web/authorize.qtpl:41
qw422016.N().S(`
<a href="`)
//line web/authorize.qtpl:41
//line web/authorize.qtpl:42
qw422016.E().S(p.Client.GetURL().String())
//line web/authorize.qtpl:41
//line web/authorize.qtpl:42
qw422016.N().S(`">
`)
//line web/authorize.qtpl:42
//line web/authorize.qtpl:43
}
//line web/authorize.qtpl:42
//line web/authorize.qtpl:43
qw422016.N().S(`
`)
//line web/authorize.qtpl:43
//line web/authorize.qtpl:44
if p.Client.GetName() != "" {
//line web/authorize.qtpl:43
//line web/authorize.qtpl:44
qw422016.N().S(`
`)
//line web/authorize.qtpl:44
//line web/authorize.qtpl:45
qw422016.E().S(p.Client.GetName())
//line web/authorize.qtpl:44
//line web/authorize.qtpl:45
qw422016.N().S(`
`)
//line web/authorize.qtpl:45
//line web/authorize.qtpl:46
} else {
//line web/authorize.qtpl:45
//line web/authorize.qtpl:46
qw422016.N().S(`
`)
//line web/authorize.qtpl:46
//line web/authorize.qtpl:47
qw422016.E().S(p.Client.ID.String())
//line web/authorize.qtpl:46
//line web/authorize.qtpl:47
qw422016.N().S(`
`)
//line web/authorize.qtpl:47
//line web/authorize.qtpl:48
}
//line web/authorize.qtpl:47
//line web/authorize.qtpl:48
qw422016.N().S(`
`)
//line web/authorize.qtpl:48
//line web/authorize.qtpl:49
if p.Client.GetURL() != nil {
//line web/authorize.qtpl:48
//line web/authorize.qtpl:49
qw422016.N().S(`
</a>
`)
//line web/authorize.qtpl:50
//line web/authorize.qtpl:51
}
//line web/authorize.qtpl:50
//line web/authorize.qtpl:51
qw422016.N().S(`
</h2>
</header>
@ -193,68 +194,68 @@ func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
target="_self">
`)
//line web/authorize.qtpl:64
//line web/authorize.qtpl:65
if p.CSRF != nil {
//line web/authorize.qtpl:64
//line web/authorize.qtpl:65
qw422016.N().S(`
<input
type="hidden"
name="_csrf"
value="`)
//line web/authorize.qtpl:68
//line web/authorize.qtpl:69
qw422016.E().Z(p.CSRF)
//line web/authorize.qtpl:68
//line web/authorize.qtpl:69
qw422016.N().S(`">
`)
//line web/authorize.qtpl:69
//line web/authorize.qtpl:70
}
//line web/authorize.qtpl:69
//line web/authorize.qtpl:70
qw422016.N().S(`
`)
//line web/authorize.qtpl:71
//line web/authorize.qtpl:72
for key, val := range map[string]string{
"client_id": p.Client.ID.String(),
"redirect_uri": p.RedirectURI.String(),
"response_type": p.ResponseType.String(),
"state": p.State,
} {
//line web/authorize.qtpl:76
//line web/authorize.qtpl:77
qw422016.N().S(`
<input
type="hidden"
name="`)
//line web/authorize.qtpl:79
//line web/authorize.qtpl:80
qw422016.E().S(key)
//line web/authorize.qtpl:79
//line web/authorize.qtpl:80
qw422016.N().S(`"
value="`)
//line web/authorize.qtpl:80
//line web/authorize.qtpl:81
qw422016.E().S(val)
//line web/authorize.qtpl:80
//line web/authorize.qtpl:81
qw422016.N().S(`">
`)
//line web/authorize.qtpl:81
//line web/authorize.qtpl:82
}
//line web/authorize.qtpl:81
//line web/authorize.qtpl:82
qw422016.N().S(`
`)
//line web/authorize.qtpl:83
//line web/authorize.qtpl:84
if len(p.Scope) > 0 {
//line web/authorize.qtpl:83
//line web/authorize.qtpl:84
qw422016.N().S(`
<fieldset>
<legend>`)
//line web/authorize.qtpl:85
//line web/authorize.qtpl:86
p.StreamT(qw422016, "Choose your scopes")
//line web/authorize.qtpl:85
//line web/authorize.qtpl:86
qw422016.N().S(`</legend>
`)
//line web/authorize.qtpl:87
//line web/authorize.qtpl:88
for _, scope := range p.Scope {
//line web/authorize.qtpl:87
//line web/authorize.qtpl:88
qw422016.N().S(`
<div>
<label>
@ -262,76 +263,131 @@ func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
type="checkbox"
name="scope[]"
value="`)
//line web/authorize.qtpl:93
//line web/authorize.qtpl:94
qw422016.E().S(scope.String())
//line web/authorize.qtpl:93
//line web/authorize.qtpl:94
qw422016.N().S(`"
checked>
`)
//line web/authorize.qtpl:96
//line web/authorize.qtpl:97
qw422016.E().S(scope.String())
//line web/authorize.qtpl:96
//line web/authorize.qtpl:97
qw422016.N().S(`
</label>
</div>
`)
//line web/authorize.qtpl:99
//line web/authorize.qtpl:100
}
//line web/authorize.qtpl:99
//line web/authorize.qtpl:100
qw422016.N().S(`
</fieldset>
`)
//line web/authorize.qtpl:101
//line web/authorize.qtpl:102
}
//line web/authorize.qtpl:101
//line web/authorize.qtpl:102
qw422016.N().S(`
`)
//line web/authorize.qtpl:103
//line web/authorize.qtpl:104
if p.CodeChallenge != "" {
//line web/authorize.qtpl:103
//line web/authorize.qtpl:104
qw422016.N().S(`
<input
type="hidden"
name="code_challenge"
value="`)
//line web/authorize.qtpl:107
//line web/authorize.qtpl:108
qw422016.E().S(p.CodeChallenge)
//line web/authorize.qtpl:107
//line web/authorize.qtpl:108
qw422016.N().S(`">
<input
type="hidden"
name="code_challenge_method"
value="`)
//line web/authorize.qtpl:112
//line web/authorize.qtpl:113
qw422016.E().S(p.CodeChallengeMethod.String())
//line web/authorize.qtpl:112
//line web/authorize.qtpl:113
qw422016.N().S(`">
`)
//line web/authorize.qtpl:113
//line web/authorize.qtpl:114
}
//line web/authorize.qtpl:113
//line web/authorize.qtpl:114
qw422016.N().S(`
`)
//line web/authorize.qtpl:115
//line web/authorize.qtpl:116
if p.Me != nil {
//line web/authorize.qtpl:115
//line web/authorize.qtpl:116
qw422016.N().S(`
<input
type="hidden"
name="me"
value="`)
//line web/authorize.qtpl:119
//line web/authorize.qtpl:120
qw422016.E().S(p.Me.String())
//line web/authorize.qtpl:119
//line web/authorize.qtpl:120
qw422016.N().S(`">
`)
//line web/authorize.qtpl:120
//line web/authorize.qtpl:121
}
//line web/authorize.qtpl:120
//line web/authorize.qtpl:121
qw422016.N().S(`
`)
//line web/authorize.qtpl:123
if len(p.Providers) > 0 {
//line web/authorize.qtpl:123
qw422016.N().S(`
<select
name="provider"
autocomplete
required>
`)
//line web/authorize.qtpl:129
for _, provider := range p.Providers {
//line web/authorize.qtpl:129
qw422016.N().S(`
<option
value="`)
//line web/authorize.qtpl:131
qw422016.E().S(provider.UID)
//line web/authorize.qtpl:131
qw422016.N().S(`"
`)
//line web/authorize.qtpl:132
if provider.UID == "mastodon" {
//line web/authorize.qtpl:132
qw422016.N().S(`selected`)
//line web/authorize.qtpl:132
}
//line web/authorize.qtpl:132
qw422016.N().S(`>
`)
//line web/authorize.qtpl:134
qw422016.E().S(provider.Name)
//line web/authorize.qtpl:134
qw422016.N().S(`
</option>
`)
//line web/authorize.qtpl:136
}
//line web/authorize.qtpl:136
qw422016.N().S(`
</select>
`)
//line web/authorize.qtpl:138
} else {
//line web/authorize.qtpl:138
qw422016.N().S(`
<input type="hidden" name="provider" value="direct">
`)
//line web/authorize.qtpl:140
}
//line web/authorize.qtpl:140
qw422016.N().S(`
<button
@ -340,9 +396,9 @@ func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
value="deny">
`)
//line web/authorize.qtpl:127
//line web/authorize.qtpl:147
p.StreamT(qw422016, "Deny")
//line web/authorize.qtpl:127
//line web/authorize.qtpl:147
qw422016.N().S(`
</button>
@ -352,39 +408,39 @@ func (p *AuthorizePage) StreamBody(qw422016 *qt422016.Writer) {
value="allow">
`)
//line web/authorize.qtpl:135
//line web/authorize.qtpl:155
p.StreamT(qw422016, "Allow")
//line web/authorize.qtpl:135
//line web/authorize.qtpl:155
qw422016.N().S(`
</button>
</form>
</main>
`)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
}
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
func (p *AuthorizePage) WriteBody(qq422016 qtio422016.Writer) {
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
qw422016 := qt422016.AcquireWriter(qq422016)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
p.StreamBody(qw422016)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
qt422016.ReleaseWriter(qw422016)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
}
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
func (p *AuthorizePage) Body() string {
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
qb422016 := qt422016.AcquireByteBuffer()
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
p.WriteBody(qb422016)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
qs422016 := string(qb422016.B)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
qt422016.ReleaseByteBuffer(qb422016)
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
return qs422016
//line web/authorize.qtpl:139
//line web/authorize.qtpl:159
}

42
web/error.qtpl Normal file
View File

@ -0,0 +1,42 @@
{% import (
"errors"
"source.toby3d.me/website/indieauth/internal/domain"
) %}
{% code type ErrorPage struct {
BaseOf
Error error
} %}
{% collapsespace %}
{% func (p *ErrorPage) Title() %}
{%s p.T("Error") %}
{% endfunc %}
{% func (p *ErrorPage) Body() %}
<main>
{% code err := new(domain.Error) %}
{% if errors.As(p.Error, err) %}
<h1>{%s err.Code.String() %}</h1>
{% if err.Description != "" %}
<p>{%s err.Description %}</p>
{% endif %}
{% if err.URI != "" %}
<a
rel="noreferrer noopener"
href="{%s err.URI %}"
target="_blank">
{%s p.T("How do I fix it?") %}
</a>
{% endif %}
{% else %}
<h1>{%s p.T("Error") %}</h1>
<p>{%s p.Error.Error() %}</p>
{% endif %}
</main>
{% endfunc %}
{% endcollapsespace %}

158
web/error.qtpl.go Normal file
View File

@ -0,0 +1,158 @@
// Code generated by qtc from "error.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line web/error.qtpl:1
package web
//line web/error.qtpl:1
import (
"errors"
"source.toby3d.me/website/indieauth/internal/domain"
)
//line web/error.qtpl:7
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line web/error.qtpl:7
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line web/error.qtpl:7
type ErrorPage struct {
BaseOf
Error error
}
//line web/error.qtpl:13
func (p *ErrorPage) StreamTitle(qw422016 *qt422016.Writer) {
//line web/error.qtpl:13
qw422016.N().S(` `)
//line web/error.qtpl:14
qw422016.E().S(p.T("Error"))
//line web/error.qtpl:14
qw422016.N().S(` `)
//line web/error.qtpl:15
}
//line web/error.qtpl:15
func (p *ErrorPage) WriteTitle(qq422016 qtio422016.Writer) {
//line web/error.qtpl:15
qw422016 := qt422016.AcquireWriter(qq422016)
//line web/error.qtpl:15
p.StreamTitle(qw422016)
//line web/error.qtpl:15
qt422016.ReleaseWriter(qw422016)
//line web/error.qtpl:15
}
//line web/error.qtpl:15
func (p *ErrorPage) Title() string {
//line web/error.qtpl:15
qb422016 := qt422016.AcquireByteBuffer()
//line web/error.qtpl:15
p.WriteTitle(qb422016)
//line web/error.qtpl:15
qs422016 := string(qb422016.B)
//line web/error.qtpl:15
qt422016.ReleaseByteBuffer(qb422016)
//line web/error.qtpl:15
return qs422016
//line web/error.qtpl:15
}
//line web/error.qtpl:17
func (p *ErrorPage) StreamBody(qw422016 *qt422016.Writer) {
//line web/error.qtpl:17
qw422016.N().S(` <main> `)
//line web/error.qtpl:19
err := new(domain.Error)
//line web/error.qtpl:19
qw422016.N().S(` `)
//line web/error.qtpl:20
if errors.As(p.Error, err) {
//line web/error.qtpl:20
qw422016.N().S(` <h1>`)
//line web/error.qtpl:21
qw422016.E().S(err.Code.String())
//line web/error.qtpl:21
qw422016.N().S(`</h1> `)
//line web/error.qtpl:23
if err.Description != "" {
//line web/error.qtpl:23
qw422016.N().S(` <p>`)
//line web/error.qtpl:24
qw422016.E().S(err.Description)
//line web/error.qtpl:24
qw422016.N().S(`</p> `)
//line web/error.qtpl:25
}
//line web/error.qtpl:25
qw422016.N().S(` `)
//line web/error.qtpl:27
if err.URI != "" {
//line web/error.qtpl:27
qw422016.N().S(` <a rel="noreferrer noopener" href="`)
//line web/error.qtpl:30
qw422016.E().S(err.URI)
//line web/error.qtpl:30
qw422016.N().S(`" target="_blank"> `)
//line web/error.qtpl:33
qw422016.E().S(p.T("How do I fix it?"))
//line web/error.qtpl:33
qw422016.N().S(` </a> `)
//line web/error.qtpl:35
}
//line web/error.qtpl:35
qw422016.N().S(` `)
//line web/error.qtpl:36
} else {
//line web/error.qtpl:36
qw422016.N().S(` <h1>`)
//line web/error.qtpl:37
qw422016.E().S(p.T("Error"))
//line web/error.qtpl:37
qw422016.N().S(`</h1> <p>`)
//line web/error.qtpl:38
qw422016.E().S(p.Error.Error())
//line web/error.qtpl:38
qw422016.N().S(`</p> `)
//line web/error.qtpl:39
}
//line web/error.qtpl:39
qw422016.N().S(` </main> `)
//line web/error.qtpl:41
}
//line web/error.qtpl:41
func (p *ErrorPage) WriteBody(qq422016 qtio422016.Writer) {
//line web/error.qtpl:41
qw422016 := qt422016.AcquireWriter(qq422016)
//line web/error.qtpl:41
p.StreamBody(qw422016)
//line web/error.qtpl:41
qt422016.ReleaseWriter(qw422016)
//line web/error.qtpl:41
}
//line web/error.qtpl:41
func (p *ErrorPage) Body() string {
//line web/error.qtpl:41
qb422016 := qt422016.AcquireByteBuffer()
//line web/error.qtpl:41
p.WriteBody(qb422016)
//line web/error.qtpl:41
qs422016 := string(qb422016.B)
//line web/error.qtpl:41
qt422016.ReleaseByteBuffer(qb422016)
//line web/error.qtpl:41
return qs422016
//line web/error.qtpl:41
}