mirror of
https://github.com/zitadel/zitadel.git
synced 2025-10-26 19:48:55 +00:00
feat: Login, OP Support and Auth Queries (#177)
* fix: change oidc config * fix: change oidc config secret * begin models * begin repo * fix: implement grpc app funcs * fix: add application requests * fix: converter * fix: converter * fix: converter and generate clientid * fix: tests * feat: project grant aggregate * feat: project grant * fix: project grant check if role existing * fix: project grant requests * fix: project grant fixes * fix: project grant member model * fix: project grant member aggregate * fix: project grant member eventstore * fix: project grant member requests * feat: user model * begin repo * repo models and more * feat: user command side * lots of functions * user command side * profile requests * commit before rebase on user * save * local config with gopass and more * begin new auth command (user centric) * Update internal/user/model/user.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/address.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/address.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/email.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/email.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/email.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/mfa.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/mfa.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/password.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/password.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/password.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/phone.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/phone.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/phone.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/user.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/user.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/model/user.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/usergrant/repository/eventsourcing/model/user_grant.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/usergrant/repository/eventsourcing/model/user_grant.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/usergrant/repository/eventsourcing/user_grant.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/user_test.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * Update internal/user/repository/eventsourcing/eventstore_mock_test.go Co-Authored-By: Livio Amstutz <livio.a@gmail.com> * changes from mr review * save files into basedir * changes from mr review * changes from mr review * move to auth request * Update internal/usergrant/repository/eventsourcing/cache.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/usergrant/repository/eventsourcing/cache.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * changes requested on mr * fix generate codes * fix return if no events * password code * email verification step * more steps * lot of mfa * begin tests * more next steps * auth api * auth api (user) * auth api (user) * auth api (user) * differ requests * merge * tests * fix compilation error * mock for id generator * Update internal/user/repository/eventsourcing/model/password.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/user/repository/eventsourcing/model/user.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * requests of mr * check email * begin separation of command and query * otp * change packages * some cleanup and fixes * tests for auth request / next steps * add VerificationLifetimes to config and make it run * tests * fix code challenge validation * cleanup * fix merge * begin view * repackaging tests and configs * fix startup config for auth * add migration * add PromptSelectAccount * fix copy / paste * remove user_agent files * fixes * fix sequences in user_session * token commands * token queries and signout * fix * fix set password test * add token handler and table * handle session init * add session state * add user view test cases * change VerifyMyMfaOTP * some fixes * fix user repo in auth api * cleanup * add user session view test * fix merge * begin oidc * user agent and more * config * keys * key command and query * add login statics * key handler * start login * login handlers * lot of fixes * merge oidc * add missing exports * add missing exports * fix some bugs * authrequestid in htmls * getrequest * update auth request * fix userid check * add username to authrequest * fix user session and auth request handling * fix UserSessionsByAgentID * fix auth request tests * fix user session on UserPasswordChanged and MfaOtpRemoved * fix MfaTypesSetupPossible * handle mfa * fill username * auth request query checks new events * fix userSessionByIDs * fix tokens * fix userSessionByIDs test * add user selection * init code * user code creation date * add init user step * add verification failed types * add verification failures * verify init code * user init code handle * user init code handle * fix userSessionByIDs * update logging * user agent cookie * browserinfo from request * add DeleteAuthRequest * add static login files to binary * add login statik to build * move generate to separate file and remove statik.go files * remove static dirs from startup.yaml * generate into separate namespaces * merge master * auth request code * auth request type mapping * fix keys * improve tokens * improve register and basic styling * fix ailerons font * improve password reset * add audience to token * all oidc apps as audience * fix test nextStep * fix email texts * remove "not set" * lot of style changes * improve copy to clipboard * fix footer * add cookie handler * remove placeholders * fix compilation after merge * fix auth config * remove comments * typo * use new secrets store * change default pws to match default policy * fixes * add todo * enable login * fix db name * Auth queries (#179) * my usersession * org structure/ auth handlers * working user grant spooler * auth internal user grants * search my project orgs * remove permissions file * my zitadel permissions * my zitadel permissions * remove unused code * authz * app searches in view * token verification * fix user grant load * fix tests * fix tests * read configs * remove unused const * remove todos * env variables * app_name * working authz * search projects * global resourceowner * Update internal/api/auth/permissions.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/api/auth/permissions.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * model2 rename * at least it works * check token expiry * search my user grants * remove token table from authz Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix test * fix ports and enable console Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
32
internal/login/static/templates/change_password.html
Normal file
32
internal/login/static/templates/change_password.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "PasswordChange.Title"}}</h1>
|
||||
<p>{{t "PasswordChange.Description"}}</p>
|
||||
|
||||
<form action="{{ changePasswordUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="old_password">{{t "PasswordChange.OldPassword"}}</label>
|
||||
<input class="input" type="password" id="old_password" name="old_password" autocomplete="current-password" autofocus required>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="new_password">{{t "PasswordChange.NewPassword"}}</label>
|
||||
<input class="input" type="password" id="new-password" name="new_password" autocomplete="new-password" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" name="resend" value="false" class="primary right" >{{t "Actions.Next"}}</buttontype="submit">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
19
internal/login/static/templates/change_password_done.html
Normal file
19
internal/login/static/templates/change_password_done.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "PasswordChangeDone.Title"}}</h1>
|
||||
<p>{{t "PasswordChangeDone.Description"}}</p>
|
||||
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
9
internal/login/static/templates/error-message.html
Normal file
9
internal/login/static/templates/error-message.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{{ define "error-message" }}
|
||||
{{if .ErrMessage }}
|
||||
<div class="field">
|
||||
<div class="error">
|
||||
{{ if .ErrType }}{{ .ErrType }} - {{end}}{{ .ErrMessage }}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ end }}
|
||||
9
internal/login/static/templates/error.html
Normal file
9
internal/login/static/templates/error.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
<div>
|
||||
{{ .ErrType }}
|
||||
{{ .ErrMessage }}
|
||||
</div>
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
3
internal/login/static/templates/footer.html
Normal file
3
internal/login/static/templates/footer.html
Normal file
@@ -0,0 +1,3 @@
|
||||
{{define "footer"}}
|
||||
|
||||
{{end}}
|
||||
3
internal/login/static/templates/header.html
Normal file
3
internal/login/static/templates/header.html
Normal file
@@ -0,0 +1,3 @@
|
||||
{{define "header"}}
|
||||
<div class="logo"></div>
|
||||
{{end}}selec
|
||||
37
internal/login/static/templates/init_password.html
Normal file
37
internal/login/static/templates/init_password.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "InitPassword.Title" }}</h1>
|
||||
<p>{{t "InitPassword.Description" }}</p>
|
||||
|
||||
<form action="{{ initPasswordUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="code">{{t "InitPassword.Code"}}</label>
|
||||
<input class="input" type="text" id="code" name="code" value="{{.Code}}" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">{{t "InitPassword.NewPassword"}}</label>
|
||||
<input class="input" type="password" id="password" name="password" autocomplete="new-password" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="passwordconfirm">{{t "InitPassword.NewPasswordConfirm"}}</label>
|
||||
<input class="input" type="password" id="passwordconfirm" name="passwordconfirm" autocomplete="new-password" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" name="resend" value="false" class="primary right" >{{t "Actions.Next"}}</buttontype="submit">
|
||||
<button type="submit" name="resend" value="true" class="secondary right" formnovalidate>{{t "Actions.Resend" }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
17
internal/login/static/templates/init_password_done.html
Normal file
17
internal/login/static/templates/init_password_done.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "PasswordSetDone.Title"}}</h1>
|
||||
<p>{{t "PasswordSetDone.Description"}}</p>
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
37
internal/login/static/templates/init_user.html
Normal file
37
internal/login/static/templates/init_user.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "InitUser.Title" }}</h1>
|
||||
<p>{{t "InitUser.Description" }}</p>
|
||||
|
||||
<form action="{{ initUserUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="code">{{t "InitUser.Code"}}</label>
|
||||
<input class="input" type="text" id="code" name="code" value="{{.Code}}" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">{{t "InitUser.NewPassword"}}</label>
|
||||
<input class="input" type="password" id="password" name="password" autocomplete="new-password" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="passwordconfirm">{{t "InitUser.NewPasswordConfirm"}}</label>
|
||||
<input class="input" type="password" id="passwordconfirm" name="passwordconfirm" autocomplete="new-password" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" name="resend" value="false" class="primary right" >{{t "Actions.Next"}}</buttontype="submit">
|
||||
<button type="submit" name="resend" value="true" class="secondary right" formnovalidate>{{t "Actions.Resend" }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
17
internal/login/static/templates/init_user_done.html
Normal file
17
internal/login/static/templates/init_user_done.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "InitUserDone.Title"}}</h1>
|
||||
<p>{{t "InitUserDone.Description"}}</p>
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
27
internal/login/static/templates/login.html
Normal file
27
internal/login/static/templates/login.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
<h1>{{t "Login.Title"}}</h1>
|
||||
<p>{{t "Login.Description"}}</p>
|
||||
|
||||
<form action="{{ usernameUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="username">{{t "Login.Username"}}</label>
|
||||
<input class="input" type="text" id="username" name="username" value="{{ .UserName }}" autocomplete="username" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
<a class="default right" href="{{ registerUrl .AuthReqID }}" >{{t "Actions.Register"}}</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
15
internal/login/static/templates/logout_done.html
Normal file
15
internal/login/static/templates/logout_done.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "LogoutDone.Title"}}</h1>
|
||||
<p>{{t "LogoutDone.Description"}}</p>
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Login"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
31
internal/login/static/templates/mail_verification.html
Normal file
31
internal/login/static/templates/mail_verification.html
Normal file
@@ -0,0 +1,31 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "EmailVerification.Title"}}</h1>
|
||||
<p>{{t "EmailVerification.Description"}}</p>
|
||||
|
||||
<form action="{{ mailVerificationUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="code">{{t "EmailVerification.Code"}}</label>
|
||||
<input class="input" type="text" id="code" name="code" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" name="resend" value="false" class="primary right" >{{t "Actions.Next"}}</buttontype="submit">
|
||||
{{ if .UserID }}
|
||||
<button type="submit" name="resend" value="true" class="secondary right" formnovalidate>{{t "Actions.Resend"}}</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
19
internal/login/static/templates/mail_verified.html
Normal file
19
internal/login/static/templates/mail_verified.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "EmailVerificationDone.Title"}}</h1>
|
||||
<p>{{t "EmailVerificationDone.Description"}}</p>
|
||||
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{if .AuthReqID }}{{t "Actions.Next"}}{{else}}{{t "Actions.Login"}}{{end}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
34
internal/login/static/templates/main.html
Normal file
34
internal/login/static/templates/main.html
Normal file
@@ -0,0 +1,34 @@
|
||||
{{define "main-top"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ .Lang }}" class="{{.ThemeMode}}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
{{if .ThemeMode}}
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl (printf "css/%s.css" .ThemeMode) .Theme }}" type="text/css" media="all">
|
||||
{{else}}
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "css/dark.css" .Theme }}" type="text/css" media="(prefers-color-scheme: dark), (prefers-color-scheme: no-preference)">
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "css/light.css" .Theme }}" type="text/css" media="(prefers-color-scheme: light)">
|
||||
{{end}}
|
||||
<link rel="icon" type="image/x-icon" href="{{ resourceThemeUrl "favicon.ico" .Theme }}">
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
{{template "header" .}}
|
||||
</header>
|
||||
<div class="content">
|
||||
{{end}}
|
||||
|
||||
<!-- here goes the content -->
|
||||
|
||||
{{define "main-bottom"}}
|
||||
</div>
|
||||
</body>
|
||||
<footer>
|
||||
{{template "footer" .}}
|
||||
</footer>
|
||||
{{end}}
|
||||
19
internal/login/static/templates/mfa_init_done.html
Normal file
19
internal/login/static/templates/mfa_init_done.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "MfaInitDone.Title"}}</h1>
|
||||
<p>{{t "MfaInitDone.Description"}}</p>
|
||||
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
47
internal/login/static/templates/mfa_init_verify.html
Normal file
47
internal/login/static/templates/mfa_init_verify.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "MfaInitVerify.Title"}}</h1>
|
||||
<p>{{t "MfaInitVerify.Description"}}</p>
|
||||
|
||||
<form action="{{ mfaInitVerifyUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
||||
<input type="hidden" name="url" value="{{ .Url }}" />
|
||||
<input type="hidden" name="secret" value="{{ .Secret }}" />
|
||||
|
||||
{{if (eq .MfaType 0) }}
|
||||
<p>{{t "MfaInitVerify.OtpDescription"}}</p>
|
||||
<div id="qrcode">
|
||||
{{.QrCode}}
|
||||
</div>
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<span class="label" for="secret">{{t "MfaInitVerify.Secret"}}</span>
|
||||
<span class="input" id="secret">
|
||||
{{.Secret}}
|
||||
<span class="copy material-icons" onclick="copyToClipboard('{{ .Secret }}')">content_copy</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="code">{{t "MfaInitVerify.Code"}}</label>
|
||||
<input class="input" type="text" id="code" name="code" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
const copyToClipboard = str => {
|
||||
navigator.clipboard.writeText(str);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
30
internal/login/static/templates/mfa_prompt.html
Normal file
30
internal/login/static/templates/mfa_prompt.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "MfaPrompt.Title"}}</h1>
|
||||
|
||||
<form action="{{ mfaPromptUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="fields">
|
||||
{{ range $provider := .MfaProviders}}
|
||||
{{ $providerName := (t (printf "MfaPrompt.Provider%v" $provider)) }}
|
||||
<div class="field radio-button">
|
||||
<input id="{{ $provider }}" type="radio" name="provider" value="{{ $provider }}">
|
||||
<label for="{{ $provider }}">{{ $providerName }}</label>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
{{if not .MfaRequired}}
|
||||
<button class="default right" name="skip" value="true" type="submit" formnovalidate>{{t "Actions.Skip"}}</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
28
internal/login/static/templates/mfa_verify.html
Normal file
28
internal/login/static/templates/mfa_verify.html
Normal file
@@ -0,0 +1,28 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "MfaVerify.Title"}}</h1>
|
||||
<p>{{t "MfaVerify.Description"}}</p>
|
||||
|
||||
<form action="{{ mfaVerifyUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="mfaType" value="{{ .SelectedMfaProvider }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="code">{{t "MfaVerify.Code"}}</label>
|
||||
<input class="input" type="text" id="code" name="code" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
33
internal/login/static/templates/password.html
Normal file
33
internal/login/static/templates/password.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "Password.Title"}}</h1>
|
||||
|
||||
<form action="{{ passwordUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
<input type="hidden" name="username" value="{{ .UserName }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="password">{{t "Password.Password"}}</label>
|
||||
<input class="input" type="password" id="password" name="password" autocomplete="current-password" autofocus required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
<a href="{{ usernameChangeUrl .AuthReqID }}">
|
||||
<button class="secondary" type="button">{{t "Actions.Back"}}</button>
|
||||
</a>
|
||||
<a href="{{ passwordResetUrl .AuthReqID }}">
|
||||
<button class="secondary" type="button">{{t "Actions.ForgotPassword"}}</button>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
17
internal/login/static/templates/password_reset_done.html
Normal file
17
internal/login/static/templates/password_reset_done.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "PasswordResetDone.Title"}}</h1>
|
||||
<p>{{t "PasswordResetDone.Description"}}</p>
|
||||
<form action="{{ loginUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
61
internal/login/static/templates/register.html
Normal file
61
internal/login/static/templates/register.html
Normal file
@@ -0,0 +1,61 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
<h1>{{t "Registration.Title"}}</h1>
|
||||
<p>{{t "Registration.Description"}}</p>
|
||||
|
||||
<form action="{{ registrationUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<label class="label" for="email">{{t "Registration.Email"}}</label>
|
||||
<input class="input" type="text" id="email" name="email" autocomplete="email" value="{{ .Email }}" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="firstname">{{t "Registration.Firstname"}}</label>
|
||||
<input class="input" type="text" id="firstname" name="firstname" autocomplete="given-name" value="{{ .Firstname }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="lastname">{{t "Registration.Lastname"}}</label>
|
||||
<input class="input" type="text" id="lastname" name="lastname" autocomplete="family-name" value="{{ .Lastname }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="languages">{{t "Registration.Language"}}</label>
|
||||
<select id="languages" name="language">
|
||||
<option value=""></option>
|
||||
<option value="de" id="de" {{if (selectedLanguage "de")}} selected {{end}}>{{t "Registration.German"}}</option>
|
||||
<option value="en" id="en" {{if (selectedLanguage "en")}} selected {{end}}>{{t "Registration.English"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="genders">
|
||||
{{t "Registration.Gender"}}
|
||||
<span class="optional">{{t "optional"}}</span>
|
||||
</label>
|
||||
<select id="genders" name="gender">
|
||||
<option value=""></option>
|
||||
<option value="1" id="female" {{if (selectedGender 1)}} selected {{end}}>{{t "Registration.Female"}}</option>
|
||||
<option value="2" id="male" {{if (selectedGender 2)}} selected {{end}}>{{t "Registration.Male"}}</option>
|
||||
<option value="3" id="diverse" {{if (selectedGender 3)}} selected {{end}}>{{t "Registration.Diverse"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">{{t "Registration.Password"}}</label>
|
||||
<input class="input" type="password" id="password" name="password" autocomplete="new-password" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password2">{{t "Registration.Password2"}}</label>
|
||||
<input class="input" type="password" id="password2" name="password2" autocomplete="new-password" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
25
internal/login/static/templates/select_user.html
Normal file
25
internal/login/static/templates/select_user.html
Normal file
@@ -0,0 +1,25 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
|
||||
<h1>{{t "UserSelection.Title"}}</h1>
|
||||
<p>{{t "UserSelection.Description"}}</p>
|
||||
|
||||
<form action="{{ userSelectionUrl }}" method="POST">
|
||||
|
||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||
|
||||
<div class="actions">
|
||||
{{ range $user := .Users }}
|
||||
{{ $sessionState := (t (printf "UserSelection.SessionState%v" $user.UserSessionState)) }}
|
||||
<button type="submit" name="userID" value="{{$user.UserID}}" class="primary">
|
||||
<span class="username">{{$user.UserName}}</span>
|
||||
<span class="sessionstate">({{$sessionState}})</span>
|
||||
</button>
|
||||
{{ end }}
|
||||
<button type="submit" name="userID" value="0" class="primary">{{t "UserSelection.OtherUser"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
|
||||
Reference in New Issue
Block a user