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, "Authorize application": 1,
"Choose your scopes": 2, "Choose your scopes": 2,
"Deny": 3, "Deny": 3,
"Recipient": 7, "Error": 5,
"Resource": 8, "How do I fix it?": 6,
"Send": 9, "Recipient": 9,
"Sign In": 5, "Resource": 10,
"TicketAuth": 6, "Send": 11,
"Sign In": 7,
"TicketAuth": 8,
} }
var enIndex = []uint32{ // 11 elements var enIndex = []uint32{ // 13 elements
0x00000000, 0x00000010, 0x00000026, 0x00000039, 0x00000000, 0x00000010, 0x00000026, 0x00000039,
0x0000003e, 0x00000044, 0x0000004c, 0x00000057, 0x0000003e, 0x00000044, 0x0000004a, 0x0000005b,
0x00000061, 0x0000006a, 0x0000006f, 0x00000063, 0x0000006e, 0x00000078, 0x00000081,
} // Size: 68 bytes 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" + "\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, 0x00000000, 0x0000001f, 0x0000004d, 0x0000008e,
0x0000009f, 0x000000b2, 0x000000bd, 0x000000bd, 0x0000009f, 0x000000b2, 0x000000b2, 0x000000b2,
0x000000bd, 0x000000bd, 0x000000bd, 0x000000bd, 0x000000bd, 0x000000bd, 0x000000bd,
} // Size: 68 bytes 0x000000bd,
} // Size: 76 bytes
const ruData string = "" + // Size: 189 bytes const ruData string = "" + // Size: 189 bytes
"\x02Авторизовать %[1]s\x02Авторизовать приложение\x02Выбери предоставляе" + "\x02Авторизовать %[1]s\x02Авторизовать приложение\x02Выбери предоставляе" +
"мые разрешения\x02Отказать\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 package http
import ( import (
"bytes"
"crypto/subtle" "crypto/subtle"
"errors" "errors"
"path" "path"
@ -159,36 +160,54 @@ func (h *RequestHandler) Register(r *router.Router) {
func (h *RequestHandler) handleRender(ctx *http.RequestCtx) { func (h *RequestHandler) handleRender(ctx *http.RequestCtx) {
req := new(AuthorizeRequest) 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 { 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 return
} }
client, err := h.clients.Discovery(ctx, req.ClientID) client, err := h.clients.Discovery(ctx, req.ClientID)
if err != nil { if err != nil {
ctx.Error(err.Error(), http.StatusBadRequest) ctx.SetStatusCode(http.StatusBadRequest)
web.WriteTemplate(ctx, &web.ErrorPage{
BaseOf: baseOf,
Error: err,
})
return return
} }
if !client.ValidateRedirectURI(req.RedirectURI) { 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 return
} }
csrf, _ := ctx.UserValue(middleware.DefaultCSRFConfig.ContextKey).([]byte) 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{ web.WriteTemplate(ctx, &web.AuthorizePage{
BaseOf: web.BaseOf{ BaseOf: baseOf,
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
},
Client: client, Client: client,
CodeChallenge: req.CodeChallenge, CodeChallenge: req.CodeChallenge,
CodeChallengeMethod: req.CodeChallengeMethod, CodeChallengeMethod: req.CodeChallengeMethod,
@ -298,8 +317,7 @@ func (r *AuthorizeRequest) bind(ctx *http.RequestCtx) error {
} }
r.Scope = make(domain.Scopes, 0) r.Scope = make(domain.Scopes, 0)
if err := r.Scope.UnmarshalForm(ctx.QueryArgs().Peek("scope")); err != nil {
if err := parseScope(r.Scope, ctx.QueryArgs().Peek("scope")); err != nil {
if errors.As(err, indieAuthError) { if errors.As(err, indieAuthError) {
return indieAuthError return indieAuthError
} }
@ -334,7 +352,17 @@ func (r *VerifyRequest) bind(ctx *http.RequestCtx) error {
} }
r.Scope = make(domain.Scopes, 0) 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 { if r.ResponseType == domain.ResponseTypeID {
r.ResponseType = domain.ResponseTypeCode r.ResponseType = domain.ResponseTypeCode
@ -369,31 +397,3 @@ func (r *ExchangeRequest) bind(ctx *http.RequestCtx) error {
return nil 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))) tags, _, _ := language.ParseAcceptLanguage(string(ctx.Request.Header.Peek(http.HeaderAcceptLanguage)))
tag, _, _ := h.matcher.Match(tags...) tag, _, _ := h.matcher.Match(tags...)
baseOf := web.BaseOf{
Config: h.config,
Language: tag,
Printer: message.NewPrinter(tag),
}
csrf, _ := ctx.UserValue("csrf").([]byte) csrf, _ := ctx.UserValue("csrf").([]byte)
ctx.SetContentType(common.MIMETextHTMLCharsetUTF8)
web.WriteTemplate(ctx, &web.TicketPage{ web.WriteTemplate(ctx, &web.TicketPage{
BaseOf: web.BaseOf{ BaseOf: baseOf,
Config: h.config, CSRF: csrf,
Language: tag,
Printer: message.NewPrinter(tag),
},
CSRF: csrf,
}) })
} }

View File

@ -46,12 +46,54 @@
"translatorComment": "The name of the button to continue the application authorization process", "translatorComment": "The name of the button to continue the application authorization process",
"fuzzy": true "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", "id": "Sign In",
"message": "Sign In", "message": "Sign In",
"translation": "Sign In", "translation": "Sign In",
"translatorComment": "The name of the button in the site address entry form to start the login process", "translatorComment": "The name of the button in the site address entry form to start the login process",
"fuzzy": true "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", "translatorComment": "The name of the button to continue the application authorization process",
"fuzzy": true "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", "id": "Sign In",
"message": "Sign In", "message": "Sign In",

View File

@ -39,11 +39,41 @@
"translation": "Разрешить", "translation": "Разрешить",
"translatorComment": "Название кнопки продолжения процесса авторизациии приложения" "translatorComment": "Название кнопки продолжения процесса авторизациии приложения"
}, },
{
"id": "Error",
"message": "Error",
"translation": "Ошибка"
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": "Как исправить это?"
},
{ {
"id": "Sign In", "id": "Sign In",
"message": "Sign In", "message": "Sign In",
"translation": "Войти", "translation": "Войти",
"translatorComment": "Название кнопки в форме ввода адреса сайта для начала процесса входа" "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": "Разрешить", "translation": "Разрешить",
"translatorComment": "Название кнопки продолжения процесса авторизациии приложения" "translatorComment": "Название кнопки продолжения процесса авторизациии приложения"
}, },
{
"id": "Error",
"message": "Error",
"translation": ""
},
{
"id": "How do I fix it?",
"message": "How do I fix it?",
"translation": ""
},
{ {
"id": "Sign In", "id": "Sign In",
"message": "Sign In", "message": "Sign In",

View File

@ -2,13 +2,14 @@
{% code type AuthorizePage struct { {% code type AuthorizePage struct {
BaseOf BaseOf
CSRF []byte
Providers []*domain.Provider
Scope domain.Scopes
Client *domain.Client Client *domain.Client
RedirectURI *domain.URL
Me *domain.Me Me *domain.Me
RedirectURI *domain.URL
CodeChallengeMethod domain.CodeChallengeMethod CodeChallengeMethod domain.CodeChallengeMethod
ResponseType domain.ResponseType ResponseType domain.ResponseType
Scope domain.Scopes
CSRF []byte
CodeChallenge string CodeChallenge string
State string State string
} %} } %}
@ -119,6 +120,25 @@
value="{%s p.Me.String() %}"> value="{%s p.Me.String() %}">
{% endif %} {% 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 <button
type="submit" type="submit"
name="authorize" name="authorize"

View File

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