mirror of
https://github.com/BradNut/AdelieStack
synced 2025-09-08 17:40:20 +00:00
Fixing refine passwords, adding svelte head.
This commit is contained in:
parent
f4aa035779
commit
224380d9e2
5 changed files with 57 additions and 28 deletions
|
|
@ -1,11 +1,11 @@
|
||||||
import { z } from 'zod'
|
import type { z } from "zod";
|
||||||
|
|
||||||
export const refinePasswords = async function (confirm_password: string, password: string, ctx: z.RefinementCtx) {
|
export const refinePasswords = async (confirm_password: string, password: string, ctx: z.RefinementCtx) => {
|
||||||
comparePasswords(confirm_password, password, ctx)
|
comparePasswords(confirm_password, password, ctx)
|
||||||
checkPasswordStrength(password, ctx)
|
checkPasswordStrength(password, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
const comparePasswords = async function (confirm_password: string, password: string, ctx: z.RefinementCtx) {
|
const comparePasswords = async (confirm_password: string, password: string, ctx: z.RefinementCtx) => {
|
||||||
if (confirm_password !== password) {
|
if (confirm_password !== password) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: 'custom',
|
code: 'custom',
|
||||||
|
|
@ -15,19 +15,19 @@ const comparePasswords = async function (confirm_password: string, password: str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkPasswordStrength = async function (password: string, ctx: z.RefinementCtx) {
|
const checkPasswordStrength = async (password: string, ctx: z.RefinementCtx) => {
|
||||||
const minimumLength = password.length < 8
|
const minimumLength = password.length < 8
|
||||||
const maximumLength = password.length > 128
|
const maximumLength = password.length > 128
|
||||||
const containsUppercase = (ch: string) => /[A-Z]/.test(ch)
|
const containsUppercase = (ch: string) => /[A-Z]/.test(ch)
|
||||||
const containsLowercase = (ch: string) => /[a-z]/.test(ch)
|
const containsLowercase = (ch: string) => /[a-z]/.test(ch)
|
||||||
const containsSpecialChar = (ch: string) => /[`!@#$%^&*()_\-+=\[\]{};':"\\|,.<>\/?~ ]/.test(ch)
|
const containsSpecialChar = (ch: string) => /[`!@#$%^&*()_\-+=\[\]{};':"\\|,.<>\/?~ ]/.test(ch)
|
||||||
let countOfUpperCase = 0,
|
let countOfUpperCase = 0;
|
||||||
countOfLowerCase = 0,
|
let countOfLowerCase = 0;
|
||||||
countOfNumbers = 0,
|
let countOfNumbers = 0;
|
||||||
countOfSpecialChar = 0
|
let countOfSpecialChar = 0;
|
||||||
for (let i = 0; i < password.length; i++) {
|
for (let i = 0; i < password.length; i++) {
|
||||||
const char = password.charAt(i)
|
const char = password.charAt(i)
|
||||||
if (!isNaN(+char)) {
|
if (!Number.isNaN(+char)) {
|
||||||
countOfNumbers++
|
countOfNumbers++
|
||||||
} else if (containsUppercase(char)) {
|
} else if (containsUppercase(char)) {
|
||||||
countOfUpperCase++
|
countOfUpperCase++
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,22 @@
|
||||||
<script context="module" lang="ts">
|
<script module lang="ts">
|
||||||
import type { SuperValidated, Infer } from 'sveltekit-superforms';
|
import type { Infer, SuperValidated } from 'sveltekit-superforms';
|
||||||
|
|
||||||
interface UpdateEmailCardProps {
|
interface UpdateEmailCardProps {
|
||||||
updateEmailForm: SuperValidated<Infer<typeof updateEmailDto>>;
|
updateEmailForm: SuperValidated<Infer<typeof updateEmailDto>>;
|
||||||
verifyEmailForm: SuperValidated<Infer<typeof verifyEmailDto>>;
|
verifyEmailForm: SuperValidated<Infer<typeof verifyEmailDto>>;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '@/components/ui/card';
|
import { Button } from '$lib/components/ui/button/index.js';
|
||||||
import { Input } from '@/components/ui/input';
|
import * as Card from '$lib/components/ui/card/index.js';
|
||||||
|
import { Input } from '$lib/components/ui/input/index.js';
|
||||||
import * as Form from '@/components/ui/form';
|
import * as Form from '@/components/ui/form';
|
||||||
import { superForm } from 'sveltekit-superforms';
|
import { superForm } from 'sveltekit-superforms';
|
||||||
import * as Dialog from '@/components/ui/dialog';
|
import * as Dialog from '@/components/ui/dialog';
|
||||||
// import PinInput from '$lib/components/pin-input.svelte';
|
import * as InputOTP from '$lib/components/ui/input-otp/index.js';
|
||||||
import type { updateEmailDto } from '@/server/api/dtos/update-email.dto';
|
import type { updateEmailDto } from '$lib/dtos/update-email.dto';
|
||||||
import type { verifyEmailDto } from '@/server/api/dtos/verify-email.dto';
|
import type { verifyEmailDto } from '$lib/dtos/verify-email.dto';
|
||||||
|
|
||||||
/* ---------------------------------- props --------------------------------- */
|
/* ---------------------------------- props --------------------------------- */
|
||||||
let { updateEmailForm, verifyEmailForm }: UpdateEmailCardProps = $props();
|
let { updateEmailForm, verifyEmailForm }: UpdateEmailCardProps = $props();
|
||||||
|
|
@ -60,9 +61,11 @@
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<form method="POST" action="?/updateEmail" use:updateEmailFormEnhance>
|
<form method="POST" action="?/updateEmail" use:updateEmailFormEnhance>
|
||||||
<Form.Field form={sf_updateEmailForm} name="email">
|
<Form.Field form={sf_updateEmailForm} name="email">
|
||||||
<Form.Control let:attrs>
|
<Form.Control>
|
||||||
<Form.Label>Email</Form.Label>
|
{#snippet children({ props })}
|
||||||
<Input {...attrs} bind:value={$updateEmailFormData.email} />
|
<Form.Label>Email</Form.Label>
|
||||||
|
<Input {...props} bind:value={$updateEmailFormData.email} />
|
||||||
|
{/snippet}
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
<Form.Description />
|
<Form.Description />
|
||||||
<Form.FieldErrors />
|
<Form.FieldErrors />
|
||||||
|
|
@ -70,7 +73,9 @@
|
||||||
</form>
|
</form>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
<Card.Footer class="border-t px-6 py-4">
|
<Card.Footer class="border-t px-6 py-4">
|
||||||
<Form.Button on:click={() => submitEmailForm()}>Submit</Form.Button>
|
<Form.Button>
|
||||||
|
<button onclick={() => submitEmailForm()}>Submit</button>
|
||||||
|
</Form.Button>
|
||||||
</Card.Footer>
|
</Card.Footer>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
|
|
||||||
|
|
@ -86,15 +91,27 @@
|
||||||
</Dialog.Header>
|
</Dialog.Header>
|
||||||
<form method="POST" action="?/verifyEmail" use:verifyEmailFormEnhance>
|
<form method="POST" action="?/verifyEmail" use:verifyEmailFormEnhance>
|
||||||
<Form.Field form={sf_verifyEmailForm} name="token">
|
<Form.Field form={sf_verifyEmailForm} name="token">
|
||||||
<Form.Control let:attrs>
|
<Form.Control>
|
||||||
<Form.Label />
|
{#snippet children({ props })}
|
||||||
<!-- <PinInput {...attrs} bind:value={$verifyEmailFormData.token} placeholder="Token..." /> -->
|
<InputOTP.Root maxlength={6} {...props} bind:value={$verifyEmailFormData.token}>
|
||||||
|
{#snippet children({ cells })}
|
||||||
|
<InputOTP.Group>
|
||||||
|
{#each cells as cell}
|
||||||
|
<InputOTP.Slot {cell} />
|
||||||
|
{/each}
|
||||||
|
</InputOTP.Group>
|
||||||
|
{/snippet}
|
||||||
|
</InputOTP.Root>
|
||||||
|
{/snippet}
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
<Form.FieldErrors />
|
<Form.FieldErrors />
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
</form>
|
</form>
|
||||||
<Dialog.Footer>
|
<Dialog.Footer>
|
||||||
<Form.Button on:click={() => verifyEmailFormSubmit()}>Verify</Form.Button>
|
<Button variant="outline">Cancel</Button>
|
||||||
|
<Form.Button onclick={() => verifyEmailFormSubmit()}>
|
||||||
|
Verify
|
||||||
|
</Form.Button>
|
||||||
</Dialog.Footer>
|
</Dialog.Footer>
|
||||||
</Dialog.Content>
|
</Dialog.Content>
|
||||||
</Dialog.Root>
|
</Dialog.Root>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
<h1>Privacy Policy</h1>
|
<h1>Privacy Policy</h1>
|
||||||
<h2>Last Updated: January 2nd, 2025</h2>
|
<h2>Last Updated: January 2nd, 2025</h2>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Acme | Privacy Policy</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<p>At Acme Inc., we respect your privacy and are committed to protecting your personal information.</p>
|
<p>At Acme Inc., we respect your privacy and are committed to protecting your personal information.</p>
|
||||||
<p>We collect only the personal information that is necessary for us to provide our services to you.</p>
|
<p>We collect only the personal information that is necessary for us to provide our services to you.</p>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
<h1>Terms of Use</h1>
|
<h1>Terms of Use</h1>
|
||||||
<h2>Last Updated: January 2nd, 2025</h2>
|
<h2>Last Updated: January 2nd, 2025</h2>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Acme | Terms of Use</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<p>The following terms of user ("Terms") apply to your use of Acme Inc. ("Acme Inc.").</p>
|
<p>The following terms of user ("Terms") apply to your use of Acme Inc. ("Acme Inc.").</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -45,6 +45,10 @@
|
||||||
const { form: newPasswordFormData, enhance: newPasswordEnhance } = sf_new_password;
|
const { form: newPasswordFormData, enhance: newPasswordEnhance } = sf_new_password;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Acme | Reset Password</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<Card.Root class="mx-auto max-w-sm">
|
<Card.Root class="mx-auto max-w-sm">
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
<Card.Title class="text-2xl">Reset Password</Card.Title>
|
<Card.Title class="text-2xl">Reset Password</Card.Title>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue