@@ -4,7 +4,7 @@ import { withQuery, parsePath } from 'ufo'
4
4
import { ofetch } from 'ofetch'
5
5
import { defu } from 'defu'
6
6
import { useRuntimeConfig } from '#imports'
7
- import crypto from 'crypto '
7
+ import { type OAuthChecks , checks } from '../../utils/security '
8
8
9
9
export interface OAuthAuth0Config {
10
10
/**
@@ -48,28 +48,17 @@ export interface OAuthAuth0Config {
48
48
checks ?: OAuthChecks [ ]
49
49
}
50
50
51
- type OAuthChecks = 'pkce' | 'state'
52
51
interface OAuthConfig {
53
52
config ?: OAuthAuth0Config
54
53
onSuccess : ( event : H3Event , result : { user : any , tokens : any } ) => Promise < void > | void
55
54
onError ?: ( event : H3Event , error : H3Error ) => Promise < void > | void
56
55
}
57
56
58
- function base64URLEncode ( str : string ) {
59
- return str . replace ( / \+ / g, '-' ) . replace ( / \/ / g, '_' ) . replace ( / = / g, '' )
60
- }
61
- function randomBytes ( length : number ) {
62
- return crypto . randomBytes ( length ) . toString ( 'base64' )
63
- }
64
- function sha256 ( buffer : string ) {
65
- return crypto . createHash ( 'sha256' ) . update ( buffer ) . digest ( 'base64' )
66
- }
67
-
68
57
export function auth0EventHandler ( { config, onSuccess, onError } : OAuthConfig ) {
69
58
return eventHandler ( async ( event : H3Event ) => {
70
59
// @ts -ignore
71
60
config = defu ( config , useRuntimeConfig ( event ) . oauth ?. auth0 ) as OAuthAuth0Config
72
- const { code, state } = getQuery ( event )
61
+ const { code } = getQuery ( event )
73
62
74
63
if ( ! config . clientId || ! config . clientSecret || ! config . domain ) {
75
64
const error = createError ( {
@@ -84,19 +73,7 @@ export function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig) {
84
73
85
74
const redirectUrl = getRequestURL ( event ) . href
86
75
if ( ! code ) {
87
- // Initialize checks
88
- const checks : Record < string , string > = { }
89
- if ( config . checks ?. includes ( 'pkce' ) ) {
90
- const pkceVerifier = base64URLEncode ( randomBytes ( 32 ) )
91
- const pkceChallenge = base64URLEncode ( sha256 ( pkceVerifier ) )
92
- checks [ 'code_challenge' ] = pkceChallenge
93
- checks [ 'code_challenge_method' ] = 'S256'
94
- setCookie ( event , 'nuxt-auth-util-verifier' , pkceVerifier , { maxAge : 60 * 15 , secure : true , httpOnly : true } )
95
- }
96
- if ( config . checks ?. includes ( 'state' ) ) {
97
- checks [ 'state' ] = base64URLEncode ( randomBytes ( 32 ) )
98
- setCookie ( event , 'nuxt-auth-util-state' , checks [ 'state' ] , { maxAge : 60 * 15 , secure : true , httpOnly : true } )
99
- }
76
+ const authParam = await checks . create ( event , config . checks ) // Initialize checks
100
77
config . scope = config . scope || [ 'openid' , 'offline_access' ]
101
78
if ( config . emailRequired && ! config . scope . includes ( 'email' ) ) {
102
79
config . scope . push ( 'email' )
@@ -110,33 +87,18 @@ export function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig) {
110
87
redirect_uri : redirectUrl ,
111
88
scope : config . scope . join ( ' ' ) ,
112
89
audience : config . audience || '' ,
113
- ...checks
90
+ ...authParam
114
91
} )
115
92
)
116
93
}
117
94
118
95
// Verify checks
119
- const pkceVerifier = getCookie ( event , 'nuxt-auth-util-verifier' )
120
- setCookie ( event , 'nuxt-auth-util-verifier' , '' , { maxAge : - 1 } )
121
- const stateInCookie = getCookie ( event , 'nuxt-auth-util-state' )
122
- setCookie ( event , 'nuxt-auth-util-state' , '' , { maxAge : - 1 } )
123
- if ( config . checks ?. includes ( 'state' ) ) {
124
- if ( ! state || ! stateInCookie ) {
125
- const error = createError ( {
126
- statusCode : 401 ,
127
- message : 'Auth0 login failed: state is missing'
128
- } )
129
- if ( ! onError ) throw error
130
- return onError ( event , error )
131
- }
132
- if ( state !== stateInCookie ) {
133
- const error = createError ( {
134
- statusCode : 401 ,
135
- message : 'Auth0 login failed: state does not match'
136
- } )
137
- if ( ! onError ) throw error
138
- return onError ( event , error )
139
- }
96
+ let checkResult
97
+ try {
98
+ checkResult = await checks . use ( event , config . checks )
99
+ } catch ( error ) {
100
+ if ( ! onError ) throw error
101
+ return onError ( event , error as H3Error )
140
102
}
141
103
142
104
const tokens : any = await ofetch (
@@ -152,7 +114,7 @@ export function auth0EventHandler({ config, onSuccess, onError }: OAuthConfig) {
152
114
client_secret : config . clientSecret ,
153
115
redirect_uri : parsePath ( redirectUrl ) . pathname ,
154
116
code,
155
- code_verifier : pkceVerifier
117
+ ... checkResult
156
118
}
157
119
}
158
120
) . catch ( error => {
0 commit comments