Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/build-output.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,15 @@ describe("Forgejo 15 native integration", () => {
expect(read("navbar.tmpl")).toContain('<span class="theme-counter theme-counter-tab">{{.Team.NumMembers}}</span>');
});

it("lays out password recovery and activation like sign-in", () => {
for (const page of ["forgot_passwd.tmpl", "reset_passwd.tmpl", "activate.tmpl"]) {
const template = fs.readFileSync(path.join(ROOT_DIR, "templates", "user", "auth", page), "utf-8");
expect(template, page).toContain('<div class="registration-panel">');
expect(template, page).toContain('<img class="signin-logo"');
expect(template, page).not.toContain("ui middle very relaxed page grid");
}
});

it("matches GitHub's repository About, visibility, and code-search details", () => {
const headerStyle = fs.readFileSync(path.join(ROOT_DIR, "styles", "templates", "repo", "header.ts"), "utf-8");
const headerTemplate = fs.readFileSync(path.join(ROOT_DIR, "templates", "repo", "home_header.tmpl"), "utf-8");
Expand Down
5 changes: 5 additions & 0 deletions styles/components/signin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ const registration = css`
.signin-footer {
text-align: center;
}
/* Recovery and activation forms submit with a full-width button, as sign-in does. */
.ui.attached.segment > .inline.field > .ui.primary.button {
width: 100%;
margin: 0;
}
}
`;

Expand Down
60 changes: 60 additions & 0 deletions templates/user/auth/activate.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{{/* Forgejo 17's account activation page in the sign-in page's layout: the logo and title over the form. */}}
{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content user activate">
<div class="registration-panel">
<form class="ui form ignore-dirty tw-max-w-2xl tw-m-auto" action="{{AppSubUrl}}/user/activate" method="post">
<div class="signin-branding">
<img class="signin-logo" width="48" height="48" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
<h1 class="signin-title">{{ctx.Locale.Tr "auth.active_your_account"}}</h1>
</div>
<div class="ui attached segment">
{{template "base/alert" .}}
{{if .IsActivatePage}}
{{if .ServiceNotEnabled}}
<p class="center">{{ctx.Locale.Tr "auth.disable_register_mail"}}</p>
{{else if .ResendLimited}}
<p class="center">{{ctx.Locale.Tr "auth.resent_limit_prompt"}}</p>
{{else}}
<p>{{ctx.Locale.Tr "auth.confirmation_mail_sent_prompt" .SignedUser.Email .ActiveCodeLives}}</p>
{{end}}
{{else}}
{{if .NeedsPassword}}
<div class="required field">
<label for="password">{{ctx.Locale.Tr "password"}}</label>
<input id="password" name="password" type="password" autocomplete="off" required>
</div>
<div class="inline field">
<button class="ui primary button">{{ctx.Locale.Tr "install.confirm_password"}}</button>
</div>
<input id="code" name="code" type="hidden" value="{{.Code}}">
{{else if .IsSendRegisterMail}}
<p>{{ctx.Locale.Tr "auth.confirmation_mail_sent_prompt" .Email .ActiveCodeLives}}</p>
{{else if .IsCodeInvalid}}
<p>{{ctx.Locale.Tr "auth.invalid_code"}}</p>
{{else if .IsPasswordInvalid}}
<p>{{ctx.Locale.Tr "auth.invalid_password"}}</p>
{{else if .ManualActivationOnly}}
<p class="center">{{ctx.Locale.Tr "auth.manual_activation_only"}}</p>
{{else}}
<p>{{ctx.Locale.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email}}</p>
<div class="divider"></div>
<details class="inline field">
<summary>{{ctx.Locale.Tr "auth.change_unconfirmed_email_summary"}}</summary>

<p>{{ctx.Locale.Tr "auth.change_unconfirmed_email"}}</p>
<div class="inline field">
<label for="email">{{ctx.Locale.Tr "email"}}</label>
<input id="email" name="email" type="email" autocomplete="on">
</div>
</details>

<div class="text">
<button class="ui primary button">{{ctx.Locale.Tr "auth.resend_mail"}}</button>
</div>
{{end}}
{{end}}
</div>
</form>
</div>
</div>
{{template "base/footer" .}}
38 changes: 38 additions & 0 deletions templates/user/auth/forgot_passwd.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{/* Forgejo 17's password recovery page in the sign-in page's layout: the logo and title over the form. */}}
{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content user forgot password">
<div class="registration-panel">
<form class="ui form ignore-dirty" action="{{.Link}}" method="post">
<div class="signin-branding">
<img class="signin-logo" width="48" height="48" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
<h1 class="signin-title">{{ctx.Locale.Tr "auth.forgot_password_title"}}</h1>
</div>
<div class="ui attached segment">
{{template "base/alert" .}}
{{if .IsResetSent}}
<p>{{ctx.Locale.Tr "auth.reset_password_mail_sent_prompt" .Email .ResetPwdCodeLives}}</p>
{{else if .IsResetRequest}}
<div class="required field {{if .Err_Email}}error{{end}}">
<label for="email">{{ctx.Locale.Tr "email"}}</label>
<input id="email" name="email" type="email" value="{{.Email}}" autofocus required>
</div>
<div class="divider"></div>
<div class="inline field">
<button class="ui primary button">{{ctx.Locale.Tr "auth.send_reset_mail"}}</button>
</div>
{{else if .IsResetDisable}}
<p class="center">
{{if $.IsAdmin}}
{{ctx.Locale.Tr "auth.disable_forgot_password_mail_admin"}}
{{else}}
{{ctx.Locale.Tr "auth.disable_forgot_password_mail"}}
{{end}}
</p>
{{else if .ResendLimited}}
<p class="center">{{ctx.Locale.Tr "auth.resent_limit_prompt"}}</p>
{{end}}
</div>
</form>
</div>
</div>
{{template "base/footer" .}}
64 changes: 64 additions & 0 deletions templates/user/auth/reset_passwd.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{{/* Forgejo 17's password reset page in the sign-in page's layout: the logo and title over the form. */}}
{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content user reset password">
<div class="registration-panel">
<form class="ui form ignore-dirty" action="{{.Link}}" method="post">
<input name="code" type="hidden" value="{{.Code}}">
<div class="signin-branding">
<img class="signin-logo" width="48" height="48" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
<h1 class="signin-title">{{ctx.Locale.Tr "auth.reset_password"}}</h1>
</div>
<div class="ui attached segment">
{{template "base/alert" .}}
{{if .user_email}}
<div class="inline field">
<label for="user_name">{{ctx.Locale.Tr "email"}}</label>
<input id="user_name" type="text" value="{{.user_email}}" disabled autocorrect="off" autocapitalize="none">
</div>
{{end}}
{{if .IsResetForm}}
<div class="required field {{if .Err_Password}}error{{end}}">
<label for="password">{{ctx.Locale.Tr "settings.new_password"}}</label>
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="new-password" autofocus required>
</div>
{{if not .user_signed_in}}
<div class="inline field">
<div class="ui checkbox">
<label>{{ctx.Locale.Tr "auth.remember_me"}}</label>
<input name="remember" type="checkbox">
</div>
</div>
{{end}}
{{if .has_two_factor}}
<h4 class="ui dividing header">
{{ctx.Locale.Tr "twofa"}}
</h4>
<div class="ui warning visible message">{{ctx.Locale.Tr "settings.twofa_is_enrolled"}}</div>
{{if .scratch_code}}
<div class="required inline field {{if .Err_Token}}error{{end}}">
<label for="token">{{ctx.Locale.Tr "auth.scratch_code"}}</label>
<input id="token" name="token" type="text" autocomplete="off" autofocus required>
</div>
<input type="hidden" name="scratch_code" value="true">
{{else}}
<div class="required field {{if .Err_Passcode}}error{{end}}">
<label for="passcode">{{ctx.Locale.Tr "passcode"}}</label>
<input id="passcode" name="passcode" type="number" autocomplete="off" autofocus required>
</div>
{{end}}
{{end}}
<div class="divider"></div>
<div class="inline field">
<button class="ui primary button">{{ctx.Locale.Tr "auth.reset_password_helper"}}</button>
{{if and .has_two_factor (not .scratch_code)}}
<a href="?code={{.Code}}&scratch_code=true">{{ctx.Locale.Tr "auth.use_scratch_code"}}</a>
{{end}}
</div>
{{else}}
<p class="center">{{ctx.Locale.Tr "auth.invalid_code_forgot_password" (printf "%s/user/forgot_password" AppSubUrl)}}</p>
{{end}}
</div>
</form>
</div>
</div>
{{template "base/footer" .}}
Loading