Skip to content

Commit 95022fc

Browse files
committed
chore: linting/formatting
1 parent fc71afd commit 95022fc

File tree

9 files changed

+153
-71
lines changed

9 files changed

+153
-71
lines changed

apps/web/src/app/(public)/sign-in/_components/wizard/context.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use client'
22

3-
import type { Dispatch, PropsWithChildren, SetStateAction } from 'react';
4-
import { useCallback, useRef} from 'react'
5-
import { createContext, useContext, useState } from 'react'
3+
import type { Dispatch, PropsWithChildren, SetStateAction } from 'react'
4+
import { createContext, useCallback, useContext, useRef, useState } from 'react'
65
import { useInterval } from 'usehooks-ts'
7-
import { createPkceChallenge, createPkceVerifier } from "~/server/modules/auth/auth.pkce";
6+
7+
import {
8+
createPkceChallenge,
9+
createPkceVerifier,
10+
} from '~/server/modules/auth/auth.pkce'
811

912
interface SignInState {
1013
timer: number
@@ -54,16 +57,16 @@ export const SignInWizardProvider = ({
5457
const [timer, setTimer] = useState(delayForResendSeconds)
5558

5659
const challengeToVerifierMap = useRef(new Map<string, string>())
57-
const newChallenge = useCallback(()=>{
60+
const newChallenge = useCallback(() => {
5861
const verifier = createPkceVerifier()
5962
const challenge = createPkceChallenge(verifier)
6063
challengeToVerifierMap.current.set(challenge, verifier)
6164
return challenge
6265
}, []) // stable reference no deps
63-
const getVerifier = useCallback((challenge: string)=>{
66+
const getVerifier = useCallback((challenge: string) => {
6467
return challengeToVerifierMap.current.get(challenge)
6568
}, []) // stable reference no deps
66-
const clearVerifierMap = useCallback(()=>{
69+
const clearVerifierMap = useCallback(() => {
6770
challengeToVerifierMap.current.clear()
6871
}, []) // stable reference no deps
6972

@@ -85,7 +88,7 @@ export const SignInWizardProvider = ({
8588
resetTimer,
8689
newChallenge,
8790
getVerifier,
88-
clearVerifierMap
91+
clearVerifierMap,
8992
}}
9093
>
9194
{children}

apps/web/src/app/(public)/sign-in/_components/wizard/email/email-flow.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import { VerificationStep } from './verification-step'
88
export const EmailFlow = () => {
99
const { setVfnStepData, vfnStepData } = useSignInWizard()
1010

11-
const handleOnSuccessEmail = ({ email, otpPrefix, codeChallenge }: VfnStepData) => {
11+
const handleOnSuccessEmail = ({
12+
email,
13+
otpPrefix,
14+
codeChallenge,
15+
}: VfnStepData) => {
1216
setVfnStepData({ email, otpPrefix, codeChallenge })
1317
}
1418

apps/web/src/app/(public)/sign-in/_components/wizard/email/email-step.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ import { Controller, useForm } from 'react-hook-form'
77

88
import { TextField } from '@acme/ui/text-field'
99

10-
import type { VfnStepData } from '../context';
11-
import { useSignInWizard } from '../context'
10+
import type { VfnStepData } from '../context'
1211
import { useTRPC } from '~/trpc/react'
1312
import { emailSignInSchema } from '~/validators/auth'
13+
import { useSignInWizard } from '../context'
1414

1515
interface EmailStepProps {
1616
onNext: ({ email, otpPrefix, codeChallenge }: VfnStepData) => void
1717
}
1818
export const EmailStep = ({ onNext }: EmailStepProps) => {
1919
const { newChallenge } = useSignInWizard()
2020
const { handleSubmit, setError, control } = useForm({
21-
resolver: zodResolver(emailSignInSchema.omit({codeChallenge: true})),
21+
resolver: zodResolver(emailSignInSchema.omit({ codeChallenge: true })),
2222
defaultValues: {
2323
email: '',
24-
}
24+
},
2525
})
2626

2727
const [queryError] = useQueryState('error', { defaultValue: '' })
@@ -36,7 +36,7 @@ export const EmailStep = ({ onNext }: EmailStepProps) => {
3636

3737
const loginMutation = useMutation(
3838
trpc.auth.email.login.mutationOptions({
39-
onSuccess: (res, req)=>{
39+
onSuccess: (res, req) => {
4040
return onNext({
4141
email: res.email,
4242
otpPrefix: res.otpPrefix,
@@ -50,7 +50,9 @@ export const EmailStep = ({ onNext }: EmailStepProps) => {
5050
return (
5151
<form
5252
noValidate
53-
onSubmit={handleSubmit(({ email }) => loginMutation.mutate({ email, codeChallenge: newChallenge() }))}
53+
onSubmit={handleSubmit(({ email }) =>
54+
loginMutation.mutate({ email, codeChallenge: newChallenge() }),
55+
)}
5456
className="flex flex-1 flex-col gap-4"
5557
>
5658
<Controller

apps/web/src/app/(public)/sign-in/_components/wizard/email/verification-step.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ export const VerificationStep = () => {
2020
const [showOtpDelayMessage, setShowOtpDelayMessage] = useState(false)
2121
const trpc = useTRPC()
2222

23-
const { vfnStepData, timer, setVfnStepData, resetTimer, newChallenge, getVerifier, clearVerifierMap } = useSignInWizard()
23+
const {
24+
vfnStepData,
25+
timer,
26+
setVfnStepData,
27+
resetTimer,
28+
newChallenge,
29+
getVerifier,
30+
clearVerifierMap,
31+
} = useSignInWizard()
2432
const codeVerifier = getVerifier(vfnStepData?.codeChallenge ?? '') ?? ''
2533

2634
useInterval(
@@ -30,7 +38,7 @@ export const VerificationStep = () => {
3038
)
3139

3240
const { control, handleSubmit, resetField, setFocus, setError } = useForm({
33-
resolver: zodResolver(emailVerifyOtpSchema.omit({codeVerifier: true})),
41+
resolver: zodResolver(emailVerifyOtpSchema.omit({ codeVerifier: true })),
3442
defaultValues: {
3543
email: vfnStepData?.email ?? '',
3644
token: '',
@@ -70,7 +78,7 @@ export const VerificationStep = () => {
7078
setVfnStepData({
7179
email: res.email,
7280
otpPrefix: res.otpPrefix,
73-
codeChallenge: req.codeChallenge
81+
codeChallenge: req.codeChallenge,
7482
})
7583
resetField('token')
7684
setFocus('token')
@@ -86,7 +94,9 @@ export const VerificationStep = () => {
8694
return (
8795
<form
8896
noValidate
89-
onSubmit={handleSubmit(({email, token}) => verifyOtpMutation.mutate({email, token, codeVerifier}))}
97+
onSubmit={handleSubmit(({ email, token }) =>
98+
verifyOtpMutation.mutate({ email, token, codeVerifier }),
99+
)}
90100
className="flex flex-1 flex-col gap-4"
91101
>
92102
<Controller

apps/web/src/server/modules/auth/__tests__/auth.utils.spec.ts

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@ describe('auth.utils', () => {
1212
const codeChallenge1 = 'codeChallenge-1'
1313
const codeChallenge2 = 'codeChallenge-2'
1414

15-
const identifier1 = createVfnIdentifier({ email, codeChallenge: codeChallenge1 })
16-
const identifier2 = createVfnIdentifier({ email, codeChallenge: codeChallenge2 })
15+
const identifier1 = createVfnIdentifier({
16+
email,
17+
codeChallenge: codeChallenge1,
18+
})
19+
const identifier2 = createVfnIdentifier({
20+
email,
21+
codeChallenge: codeChallenge2,
22+
})
1723

1824
expect(identifier1).not.toBe(identifier2)
1925
})
@@ -22,18 +28,25 @@ describe('auth.utils', () => {
2228
const email = '[email protected]'
2329
const codeChallenge = 'test-codeChallenge'
2430

25-
const identifier1 = createVfnIdentifier({ email, codeChallenge: codeChallenge })
26-
const identifier2 = createVfnIdentifier({ email, codeChallenge: codeChallenge })
27-
const identifier3 = createVfnIdentifier({ email, codeChallenge: codeChallenge })
31+
const identifier1 = createVfnIdentifier({
32+
email,
33+
codeChallenge: codeChallenge,
34+
})
35+
const identifier2 = createVfnIdentifier({
36+
email,
37+
codeChallenge: codeChallenge,
38+
})
39+
const identifier3 = createVfnIdentifier({
40+
email,
41+
codeChallenge: codeChallenge,
42+
})
2843

2944
expect(identifier1).toBe(identifier2)
3045
expect(identifier2).toBe(identifier3)
3146
})
3247
})
3348

3449
describe('createVfnPrefix', () => {
35-
36-
3750
it('should only contain uppercase letters from the allowed alphabet', () => {
3851
const prefix = createVfnPrefix()
3952
const allowedChars = /^[ABCDEFGHJKLMNPQRSTUVWXYZ]+$/
@@ -70,18 +83,30 @@ describe('auth.utils', () => {
7083

7184
it('should generate tokens of sufficient entropy', () => {
7285
const N = 10000
73-
const tokens = Array.from({length: N}).map(()=>createAuthToken({
74-
email: testEmail,
75-
codeChallenge: testCodeChallenge,
76-
}).token)
86+
const tokens = Array.from({ length: N }).map(
87+
() =>
88+
createAuthToken({
89+
email: testEmail,
90+
codeChallenge: testCodeChallenge,
91+
}).token,
92+
)
7793

7894
expect(new Set(tokens).size).toBe(N)
7995
})
8096

8197
it('should generate different tokens for the same email and codeChallenge on multiple calls', () => {
82-
const result1 = createAuthToken({ email: testEmail, codeChallenge: testCodeChallenge })
83-
const result2 = createAuthToken({ email: testEmail, codeChallenge: testCodeChallenge })
84-
const result3 = createAuthToken({ email: testEmail, codeChallenge: testCodeChallenge })
98+
const result1 = createAuthToken({
99+
email: testEmail,
100+
codeChallenge: testCodeChallenge,
101+
})
102+
const result2 = createAuthToken({
103+
email: testEmail,
104+
codeChallenge: testCodeChallenge,
105+
})
106+
const result3 = createAuthToken({
107+
email: testEmail,
108+
codeChallenge: testCodeChallenge,
109+
})
85110

86111
expect(result1.token).not.toBe(result2.token)
87112
expect(result2.token).not.toBe(result3.token)
@@ -92,8 +117,14 @@ describe('auth.utils', () => {
92117
const email1 = '[email protected]'
93118
const email2 = '[email protected]'
94119

95-
const result1 = createAuthToken({ email: email1, codeChallenge: testCodeChallenge })
96-
const result2 = createAuthToken({ email: email2, codeChallenge: testCodeChallenge })
120+
const result1 = createAuthToken({
121+
email: email1,
122+
codeChallenge: testCodeChallenge,
123+
})
124+
const result2 = createAuthToken({
125+
email: email2,
126+
codeChallenge: testCodeChallenge,
127+
})
97128

98129
// Hashes should be different due to email being used as salt
99130
expect(result1.hashedToken).not.toBe(result2.hashedToken)
@@ -103,8 +134,14 @@ describe('auth.utils', () => {
103134
const codeChallenge1 = 'codeChallenge-1'
104135
const codeChallenge2 = 'codeChallenge-2'
105136

106-
const result1 = createAuthToken({ email: testEmail, codeChallenge: codeChallenge1 })
107-
const result2 = createAuthToken({ email: testEmail, codeChallenge: codeChallenge2 })
137+
const result1 = createAuthToken({
138+
email: testEmail,
139+
codeChallenge: codeChallenge1,
140+
})
141+
const result2 = createAuthToken({
142+
email: testEmail,
143+
codeChallenge: codeChallenge2,
144+
})
108145

109146
// Hashes should be different due to codeChallenge being part of the hash input
110147
expect(result1.hashedToken).not.toBe(result2.hashedToken)
@@ -114,7 +151,11 @@ describe('auth.utils', () => {
114151
// Generate multiple tokens to ensure consistency
115152
const tokens = Array.from(
116153
{ length: 50 },
117-
() => createAuthToken({ email: testEmail, codeChallenge: testCodeChallenge }).token,
154+
() =>
155+
createAuthToken({
156+
email: testEmail,
157+
codeChallenge: testCodeChallenge,
158+
}).token,
118159
)
119160
const combinedString = tokens.join('')
120161

@@ -150,7 +191,10 @@ describe('auth.utils', () => {
150191
email: testEmail,
151192
codeChallenge: testCodeChallenge,
152193
})
153-
const {token: invalidToken} = createAuthToken({email: testEmail, codeChallenge: testCodeChallenge})
194+
const { token: invalidToken } = createAuthToken({
195+
email: testEmail,
196+
codeChallenge: testCodeChallenge,
197+
})
154198

155199
const isValid = isValidToken({
156200
token: invalidToken,
@@ -291,13 +335,21 @@ describe('auth.utils', () => {
291335
]
292336

293337
const tokens = users.map(({ email, codeChallenge }) => {
294-
const { token, hashedToken } = createAuthToken({ email, codeChallenge: codeChallenge })
338+
const { token, hashedToken } = createAuthToken({
339+
email,
340+
codeChallenge: codeChallenge,
341+
})
295342
return { email, codeChallenge, token, hashedToken }
296343
})
297344

298345
// Verify each token is valid for its own email and codeChallenge
299346
tokens.forEach(({ email, codeChallenge, token, hashedToken }) => {
300-
const isValid = isValidToken({ token, email, codeChallenge: codeChallenge, hash: hashedToken })
347+
const isValid = isValidToken({
348+
token,
349+
email,
350+
codeChallenge: codeChallenge,
351+
hash: hashedToken,
352+
})
301353
expect(isValid).toBe(true)
302354
})
303355

@@ -344,10 +396,20 @@ describe('auth.utils', () => {
344396

345397
// But each token should still work with its own codeChallenge
346398
expect(
347-
isValidToken({ token: token1, email, codeChallenge: codeChallenge1, hash: hash1 }),
399+
isValidToken({
400+
token: token1,
401+
email,
402+
codeChallenge: codeChallenge1,
403+
hash: hash1,
404+
}),
348405
).toBe(true)
349406
expect(
350-
isValidToken({ token: token2, email, codeChallenge: codeChallenge2, hash: hash2 }),
407+
isValidToken({
408+
token: token2,
409+
email,
410+
codeChallenge: codeChallenge2,
411+
hash: hash2,
412+
}),
351413
).toBe(true)
352414
})
353415
})
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
import { createHash } from 'crypto';
2-
import { customAlphabet } from "nanoid";
3-
import { PKCE_LENGTH } from "~/validators/auth";
1+
import { createHash } from 'crypto'
2+
import { customAlphabet } from 'nanoid'
3+
4+
import { PKCE_LENGTH } from '~/validators/auth'
45

56
// This file hosts functions pertaining to PKCE (Proof Key for Code Exchange) as per RFC 7636
67
// If you need to understand PKCE, read https://datatracker.ietf.org/doc/html/rfc7636
78
// Do not use this for actual OAuth flows, please use a tested library instead.
89

910
const PKCE_VERIFIER_ALPHABET =
10-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
11+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'
1112
const verifierGenerator = customAlphabet(
1213
PKCE_VERIFIER_ALPHABET,
1314
PKCE_LENGTH, // max length as per RFC 7636
14-
);
15+
)
1516

1617
export function createPkceVerifier(): string {
17-
return verifierGenerator();
18+
return verifierGenerator()
1819
}
1920

2021
export function createPkceChallenge(codeVerifier: string): string {
@@ -23,6 +24,6 @@ export function createPkceChallenge(codeVerifier: string): string {
2324
.digest('base64')
2425
.replace(/=/g, '')
2526
.replace(/\+/g, '-')
26-
.replace(/\//g, '_');
27+
.replace(/\//g, '_')
2728
// convert to base64url manually since polyfill not working
28-
}
29+
}

0 commit comments

Comments
 (0)