-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c69742f
commit 80942a9
Showing
86 changed files
with
2,332 additions
and
1,509 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"use client" | ||
|
||
import { z } from 'zod' | ||
import Link from 'next/link' | ||
import Image from 'next/image' | ||
import jwt from 'jsonwebtoken' | ||
import { signIn } from "next-auth/react" | ||
import { useTranslations } from 'next-intl' | ||
|
||
import gravatar from '@/helpers/gravatar' | ||
|
||
import Form from '@/components/Form' | ||
|
||
import aLogo from '@/assets/logo.webp' | ||
|
||
const callbackUrl = '/dashboard' | ||
|
||
export default function Component({ token, email }: { token: string, email: string }) { | ||
const t = useTranslations('auth') | ||
|
||
const onSubmit = async ({ password }: any) => { | ||
const { ok, status } = await fetch('/api/auth/forgot/update', { method: 'POST', body: JSON.stringify({ token, password }) }) | ||
|
||
if (status == 401) return new Error(t('password-reset-has-expired')) | ||
if (!ok) return new Error(t('sorry-something-unexpected-happened')) | ||
|
||
signIn('credentials', { email, password, callbackUrl }) | ||
} | ||
|
||
return ( | ||
<div className="flex min-h-full flex-1 flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||
<div className="sm:mx-auto sm:w-full sm:max-w-md"> | ||
<Link href="/"> | ||
<Image | ||
className="mx-auto h-10 w-auto" | ||
src={aLogo} | ||
alt="" | ||
/> | ||
</Link> | ||
<h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"> | ||
{t('update-your-password')} | ||
</h2> | ||
</div> | ||
|
||
<div className="relative my-10 sm:mx-auto sm:w-full sm:max-w-[480px]"> | ||
<div className="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12 flex flex-col gap-y-4"> | ||
<div className="flex flex-col items-center justify-center gap-y-4"> | ||
<Image | ||
className="h-16 w-16 rounded-full bg-gray-50 border" | ||
src={gravatar(email)} | ||
width={80} | ||
height={80} | ||
alt="" | ||
/> | ||
<p className="text-sm font-medium text-gray-900"> | ||
{email} | ||
</p> | ||
</div> | ||
|
||
<div className="mt-8"> | ||
<Form | ||
onSubmit={onSubmit} | ||
validator={ | ||
z.object({ | ||
password: z.string() | ||
.min(8, { message: t('this-password-is-too-short') }) | ||
.max(64, { message: t('this-password-is-too-long') }), | ||
repeatPassword: z.string() | ||
.min(8, { message: t('this-password-is-too-short') }) | ||
.max(64, { message: t('this-password-is-too-long') }) | ||
}).refine(({ password, repeatPassword }) => password == repeatPassword, { message: t('the-passwords-do-not-match'), path: ['repeatPassword'] }) | ||
} | ||
submit={{ label: t('confirm'), position: 'full' }} | ||
fields={[ | ||
{ id: 'password', type: 'password', label: t('password') }, | ||
{ id: 'repeatPassword', type: 'password', label: t('repeat-password') } | ||
]} | ||
options={[ | ||
'showPassword' | ||
]} | ||
/> | ||
</div> | ||
</div> | ||
|
||
<div className="absolute -bottom-10 left-5 text-center text-sm text-gray-500"> | ||
<Link href="/login"> | ||
← {t('sign-in-to-a-different-account')} | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"use client" | ||
|
||
import Link from 'next/link' | ||
import Image from 'next/image' | ||
import { useTranslations } from 'next-intl' | ||
|
||
import aLogo from '@/assets/logo.webp' | ||
|
||
export default function Error() { | ||
const t = useTranslations('auth') | ||
|
||
return ( | ||
<div className="flex min-h-full flex-1 flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||
<div className="sm:mx-auto sm:w-full sm:max-w-md"> | ||
<Link href="/"> | ||
<Image | ||
className="mx-auto h-10 w-auto" | ||
src={aLogo} | ||
alt="" | ||
/> | ||
</Link> | ||
<h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"> | ||
{t('password-reset-has-expired')} | ||
</h2> | ||
</div> | ||
|
||
<div className="relative my-10 sm:mx-auto sm:w-full sm:max-w-[480px]"> | ||
<div className="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12 flex flex-col gap-y-4"> | ||
|
||
<p className="text-sm text-center font-medium text-gray-900"> | ||
{t('the-password-reset-has-reached-its-expiration-date')} | ||
</p> | ||
|
||
<Link href="/forgot" className="mt-5 flex w-full gap-x-2 items-center justify-center rounded-md bg-primary px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-primary-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"> | ||
{t('reset-your-password-again')} | ||
</Link> | ||
|
||
<Link href='/register' className="flex items-center justify-center w-full rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"> | ||
{t('sign-up-for-a-new-account')} | ||
</Link> | ||
</div> | ||
|
||
<div className="absolute -bottom-10 left-5 text-center text-sm text-gray-500"> | ||
<Link href="/login"> | ||
← {t('sign-in-to-a-different-account')} | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import jwt from 'jsonwebtoken' | ||
|
||
import prisma from '@/prisma/client' | ||
|
||
import Reset from './Reset' | ||
|
||
export default async function Page({ params: { token } }: { params: { token: string } }) { | ||
|
||
if (!process.env.NEXTAUTH_SECRET) throw new Error('Internal server error, please try again later.') | ||
|
||
let { email }: any = jwt.decode(token) | ||
|
||
jwt.verify(token, process.env.NEXTAUTH_SECRET) | ||
|
||
const { passwordResetToken }: any = await prisma.user.findUnique({ where: { email } }) | ||
|
||
if (token != passwordResetToken) throw new Error('The password reset has reached its expiration date.') | ||
|
||
return <Reset | ||
token={token} | ||
email={email} | ||
/> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
"use client" | ||
|
||
import { z } from "zod" | ||
import Link from "next/link" | ||
import Image from 'next/image' | ||
import { useState } from "react" | ||
import { useTranslations } from "next-intl" | ||
|
||
import gravatar from "@/helpers/gravatar" | ||
|
||
import Form from "@/components/Form" | ||
|
||
import aLogo from '@/assets/logo.webp' | ||
|
||
export default function Page() { | ||
const t = useTranslations('auth') | ||
|
||
const [formEmail, setFormEmail] = useState<string>() | ||
const [hasBeenSent, setHasBeenSent] = useState<boolean>(false) | ||
|
||
const onSubmit = async ({ email }: any) => { | ||
const { ok, status } = await fetch('/api/auth/forgot', { method: 'POST', body: JSON.stringify({ email }) }) | ||
|
||
if (status == 406) return new Error(t('an-account-with-this-email-address-does-not-exists')) | ||
if (!ok) return new Error(t('sorry-something-unexpected-happened')) | ||
|
||
setFormEmail(email) | ||
setHasBeenSent(true) | ||
} | ||
|
||
return ( | ||
<div className="flex min-h-full flex-1 flex-col justify-center py-12 sm:px-6 lg:px-8"> | ||
<div className="sm:mx-auto sm:w-full sm:max-w-md"> | ||
<Link href="/"> | ||
<Image | ||
className="mx-auto h-10 w-auto" | ||
src={aLogo} | ||
alt="" | ||
/> | ||
</Link> | ||
<h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"> | ||
{t('reset-your-password')} | ||
</h2> | ||
</div> | ||
|
||
<div className="relative my-10 sm:mx-auto sm:w-full sm:max-w-[480px]"> | ||
<div className="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12"> | ||
{ | ||
hasBeenSent | ||
? <div className="flex flex-col items-center justify-center gap-y-4"> | ||
<Image | ||
className="h-16 w-16 rounded-full bg-gray-50 border" | ||
src={gravatar(formEmail ?? '')} | ||
width={80} | ||
height={80} | ||
alt="" | ||
/> | ||
<p className="text-sm font-medium text-gray-900"> | ||
{formEmail} | ||
</p> | ||
|
||
<p className="text-sm mt-4 text-center font-medium text-gray-900"> | ||
{t('we-have-sent-you-an-email-to-reset-your-password')} | ||
</p> | ||
</div> | ||
: <Form | ||
onSubmit={onSubmit} | ||
validator={ | ||
z.object({ | ||
email: z.string() | ||
.min(2, { message: t('this-email-address-is-too-short') }) | ||
.max(64, { message: t('this-email-address-is-too-long') }) | ||
.email(t('this-email-address-is-not-valid')) | ||
}) | ||
} | ||
submit={{ label: t('continue'), position: 'full' }} | ||
fields={[ | ||
{ id: 'email', type: 'email', label: t('email-address') } | ||
]} | ||
/> | ||
} | ||
</div> | ||
|
||
<div className="absolute -bottom-10 left-5 text-center text-sm text-gray-500"> | ||
<Link href="/login"> | ||
← {t('sign-in-to-your-account')} | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.