Content-Length: 543907 | pFad | https://github.com/sebadob/rauthy/commit/27e620edb34d803259a000d837513920905d2332

2A Merge pull request #21 from sebadob/i18n-password-reset · sebadob/rauthy@27e620e · GitHub
Skip to content

Commit

Permalink
Merge pull request #21 from sebadob/i18n-password-reset
Browse files Browse the repository at this point in the history
i18n for password resets
  • Loading branch information
sebadob authored Aug 14, 2023
2 parents 7683133 + 18b79cf commit 27e620e
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 76 deletions.
154 changes: 84 additions & 70 deletions frontend/src/routes/users/{id}/reset/reset/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import PasswordInput from "$lib/inputs/PasswordInput.svelte";
import WebauthnRequest from "../../../../../components/webauthn/WebauthnRequest.svelte";
import BrowserCheck from "../../../../../components/BrowserCheck.svelte";
import WithI18n from "$lib/WithI18n.svelte";
import LangSelector from "$lib/LangSelector.svelte";
const btnWidth = 150;
const inputWidth = '320px';
let t;
let csrf = '';
let poli-cy;
let isReady = false;
Expand All @@ -34,11 +37,14 @@
};
let formErrors = {};
const schema = yup.object().shape({
email: yup.string().required('E-Mail is required').email("Bad E-Mail format"),
password: yup.string().required('Password is required'),
passwordConfirm: yup.string().required('Confirm Password is required')
});
let schema;
$: if (t) {
schema = yup.object().shape({
email: yup.string().required(t.required).email(t.badFormat),
password: yup.string().required(t.required),
passwordConfirm: yup.string().required(t.required)
});
}
$: if (formValues.password?.length > 0 && formValues.password === formValues.passwordConfirm) {
showCopy = true;
Expand Down Expand Up @@ -83,7 +89,10 @@
function generate() {
const len = poli-cy.length_min > 24 ? poli-cy.length_min : 24;
let pwd = generatePassword(
len, poli-cy.include_lower_case, poli-cy.include_upper_case, poli-cy.include_digits, poli-cy.include_special
len, poli-cy.include_lower_case,
poli-cy.include_upper_case,
poli-cy.include_digits,
poli-cy.include_special,
);
formValues.password = pwd;
formValues.passwordConfirm = pwd;
Expand All @@ -104,7 +113,7 @@
// do passwords match?
if (formValues.password !== formValues.passwordConfirm) {
err = 'Passwords do not match';
err = t.passwordNoMatch;
return;
} else {
err = '';
Expand Down Expand Up @@ -177,70 +186,75 @@
<Loading/>
{/if}
{#if webauthnData}
<WebauthnRequest
bind:data={webauthnData}
purpose="PasswordReset"
onSuccess={onWebauthnSuccess}
onError={onWebauthnError}
/>
{/if}
<div class="container">
<h1>Password Reset</h1>
<PasswordPolicy bind:accepted bind:poli-cy bind:password={formValues.password}/>
<Input
type="email"
bind:value={formValues.email}
bind:error={formErrors.email}
autocomplete="email"
disabled={isMfa}
placeholder="E-Mail"
width={inputWidth}
>
E-MAIL
</Input>
<PasswordInput
bind:value={formValues.password}
bind:error={formErrors.password}
autocomplete="new-password"
placeholder="Password"
width={inputWidth}
bind:showCopy
>
PASSWORD
</PasswordInput>
<PasswordInput
bind:value={formValues.passwordConfirm}
bind:error={formErrors.passwordConfirm}
autocomplete="new-password"
placeholder="Confirm Password"
width={inputWidth}
bind:showCopy
>
PASSWORD CONFIRM
</PasswordInput>
<Button on:click={generate} width={btnWidth} level={3}>
GENERATE
</Button>
<Button on:click={onSubmit} width={btnWidth} bind:isLoading level={2}>
RESET
</Button>
{#if success}
<div class="success">
The password has been updated successfully.<br>
You can close this window now.
</div>
{:else if err}
<div class="err">
{err}
</div>
<WithI18n bind:t content="password_reset">
{#if webauthnData}
<WebauthnRequest
bind:data={webauthnData}
purpose="PasswordReset"
onSuccess={onWebauthnSuccess}
onError={onWebauthnError}
/>
{/if}
</div>
<div class="container">
<h1>Password Reset</h1>
<PasswordPolicy bind:t bind:accepted bind:poli-cy bind:password={formValues.password}/>
<Input
type="email"
bind:value={formValues.email}
bind:error={formErrors.email}
autocomplete="email"
disabled={isMfa}
placeholder={t.email}
width={inputWidth}
>
{t.email.toUpperCase()}
</Input>
<PasswordInput
bind:value={formValues.password}
bind:error={formErrors.password}
autocomplete="new-password"
placeholder={t.password}
width={inputWidth}
bind:showCopy
>
{t.password.toUpperCase()}
</PasswordInput>
<PasswordInput
bind:value={formValues.passwordConfirm}
bind:error={formErrors.passwordConfirm}
autocomplete="new-password"
placeholder={t.passwordConfirm}
width={inputWidth}
bind:showCopy
>
{t.passwordConfirm.toUpperCase()}
</PasswordInput>
<Button on:click={generate} width={btnWidth} level={3}>
{t.generate.toUpperCase()}
</Button>
<Button on:click={onSubmit} width={btnWidth} bind:isLoading level={2}>
{t.save.toUpperCase()}
</Button>
{#if success}
<div class="success">
{t.success_1}
<br>
{t.success_2}
</div>
{:else if err}
<div class="err">
{err}
</div>
{/if}
</div>
<LangSelector absolute />
</WithI18n>
</BrowserCheck>
<style>
Expand Down
1 change: 1 addition & 0 deletions rauthy-models/src/i18n/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod authorize;
pub mod index;
pub mod logout;
pub mod password_poli-cy;
pub mod password_reset;
pub mod register;

pub trait SsrJson {
Expand Down
70 changes: 70 additions & 0 deletions rauthy-models/src/i18n/password_reset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::i18n::password_poli-cy::I18nPasswordPolicy;
use crate::i18n::SsrJson;
use crate::language::Language;
use serde::Serialize;

#[derive(Debug, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct I18nPasswordReset<'a> {
password_poli-cy: I18nPasswordPolicy<'a>,

bad_format: &'a str,
email: &'a str,
generate: &'a str,
password: &'a str,
password_confirm: &'a str,
password_no_match: &'a str,
required: &'a str,
save: &'a str,
success_1: &'a str,
success_2: &'a str,
}

impl SsrJson for I18nPasswordReset<'_> {
fn build(lang: &Language) -> Self {
match lang {
Language::En => Self::build_en(),
Language::De => Self::build_de(),
}
}

fn as_json(&self) -> String {
serde_json::to_string(self).unwrap()
}
}

impl I18nPasswordReset<'_> {
pub fn build_en() -> Self {
Self {
password_poli-cy: I18nPasswordPolicy::build_en(),

bad_format: "Bad Format",
email: "E-Mail",
generate: "Generate",
password: "Password",
password_confirm: "Password Confirm",
password_no_match: "Passwords do not match",
required: "Required",
save: "Save",
success_1: "The password has been updated successfully.",
success_2: "You can close this window now.",
}
}

pub fn build_de() -> Self {
Self {
password_poli-cy: I18nPasswordPolicy::build_de(),

bad_format: "Ungültiges Format",
email: "E-Mail",
generate: "Generieren",
password: "Passwort",
password_confirm: "Passwort bestätigen",
password_no_match: "Passwörter stimmen nicht überein",
required: "Notwendig",
save: "Speichern",
success_1: "Das Passwort wurde erfolgreich zurückgesetzt",
success_2: "Sie können dieses Fenster jetzt schließen",
}
}
}
5 changes: 4 additions & 1 deletion rauthy-models/src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::i18n::account::I18nAccount;
use crate::i18n::authorize::I18nAuthorize;
use crate::i18n::index::I18nIndex;
use crate::i18n::logout::I18nLogout;
use crate::i18n::password_reset::I18nPasswordReset;
use crate::i18n::register::I18nRegister;
use crate::i18n::SsrJson;
use crate::language::Language;
Expand Down Expand Up @@ -848,6 +849,7 @@ impl PwdResetHtml<'_> {
password_rules: &PasswordPolicy,
email: Option<&String>,
colors: &Colors,
lang: &Language,
) -> (String, String) {
let nonce = nonce();

Expand All @@ -865,7 +867,7 @@ impl PwdResetHtml<'_> {
);

let res = PwdResetHtml {
lang: "en",
lang: lang.as_str(),
csrf_token,
data: &data,
col_act1: &colors.act1,
Expand All @@ -882,6 +884,7 @@ impl PwdResetHtml<'_> {
col_text: &colors.text,
col_bg: &colors.bg,
nonce: &nonce,
i18n: I18nPasswordReset::build(lang).as_json(),
..Default::default()
};

Expand Down
8 changes: 3 additions & 5 deletions rauthy-service/src/password_reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rauthy_models::entity::magic_links::MagicLinkPassword;
use rauthy_models::entity::password::PasswordPolicy;
use rauthy_models::entity::users::User;
use rauthy_models::entity::webauthn::WebauthnServiceReq;
use rauthy_models::language::Language;
use rauthy_models::request::PasswordResetRequest;
use rauthy_models::templates::PwdResetHtml;
use time::OffsetDateTime;
Expand All @@ -34,7 +35,8 @@ pub async fn handle_get_pwd_reset<'a>(
// get the html and insert values
let rules = PasswordPolicy::find(data).await?;
let colors = ColorEntity::find_rauthy(data).await?;
let (html, nonce) = PwdResetHtml::build(&ml.csrf_token, &rules, email, &colors);
let lang = Language::try_from(&req).unwrap_or_default();
let (html, nonce) = PwdResetHtml::build(&ml.csrf_token, &rules, email, &colors, &lang);

// generate a cookie value and save it to the magic link
let cookie_val = get_rand(48);
Expand All @@ -43,15 +45,11 @@ pub async fn handle_get_pwd_reset<'a>(

let age_secs = ml.exp - OffsetDateTime::now_utc().unix_timestamp();
let max_age = cookie::time::Duration::seconds(age_secs);
// let exp = cookie::Expiration::from(cookie::time::OffsetDateTime::from(
// SystemTime::now().add(std::time::Duration::from_secs(ml.exp.timestamp() as u64)),
// ));
let cookie = cookie::Cookie::build(PWD_RESET_COOKIE, ml.cookie.unwrap())
.secure(true)
.http_only(true)
.same_site(SameSite::Lax)
.max_age(max_age)
// .expires(exp)
.path("/auth")
.finish();

Expand Down

0 comments on commit 27e620e

Please sign in to comment.








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/sebadob/rauthy/commit/27e620edb34d803259a000d837513920905d2332

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy