Skip to content

Commit

Permalink
add validateUser method
Browse files Browse the repository at this point in the history
  • Loading branch information
atinux committed Sep 30, 2024
1 parent 56a7301 commit 43ffd40
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 17 deletions.
26 changes: 15 additions & 11 deletions src/runtime/server/lib/webauthn/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,13 @@ import { bufferToBase64URLString } from '@simplewebauthn/browser'
import { getRandomValues } from 'uncrypto'
import { storeChallengeAsSession, getChallengeFromSession } from './utils'
import { useRuntimeConfig } from '#imports'
import type { WebAuthnRegisterEventHandlerOptions } from '#auth-utils'
import type { WebAuthnUser, WebAuthnRegisterEventHandlerOptions } from '#auth-utils'

type RegistrationBody = {
user: {
userName: string
displayName?: string
[key: string]: unknown
}
user: WebAuthnUser
verify: false
} | {
user: {
userName: string
displayName?: string
[key: string]: unknown
}
user: WebAuthnUser
verify: true
attemptId: string
response: RegistrationResponseJSON
Expand All @@ -31,6 +23,7 @@ export function defineWebAuthnRegisterEventHandler({
storeChallenge,
getChallenge,
getOptions,
validateUser,
onSuccess,
onError,
}: WebAuthnRegisterEventHandlerOptions) {
Expand All @@ -43,6 +36,17 @@ export function defineWebAuthnRegisterEventHandler({
statusCode: 400,
})

if (validateUser) {
await validateUser(body.user).catch((error) => {
throw createError({
status: 400,
statusMessage: 'User Validation Error',
message: error?.message || 'User Validation Error',
data: error,
})
})
}

const _config = defu(await getOptions?.(event) ?? {}, useRuntimeConfig(event).webauthn.register, {
rpID: url.hostname,
rpName: url.hostname,
Expand Down
1 change: 1 addition & 0 deletions src/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export type {
WebAuthnRegisterEventHandlerOptions,
WebAuthnAuthenticateEventHandlerOptions,
WebAuthnComposable,
WebAuthnUser,
} from './webauthn'
15 changes: 9 additions & 6 deletions src/runtime/types/webauthn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ export interface WebAuthnCredential {
[key: string]: unknown
}

export interface WebAuthnUser {
userName: string
displayName?: string
[key: string]: unknown
}

// Using a discriminated union makes it such that you can only define both storeChallenge and getChallenge or neither
type WebAuthnEventHandlerBase<T extends Record<PropertyKey, unknown>> = {
storeChallenge: (event: H3Event, challenge: string, attemptId: string) => void | Promise<void>
Expand All @@ -31,15 +37,12 @@ type WebAuthnEventHandlerBase<T extends Record<PropertyKey, unknown>> = {
}

export type WebAuthnRegisterEventHandlerOptions = WebAuthnEventHandlerBase<{
user: {
userName: string
displayName?: string
[key: string]: unknown
}
user: WebAuthnUser
credential: WebAuthnCredential
registrationInfo: Exclude<VerifiedRegistrationResponse['registrationInfo'], undefined>
}> & {
getOptions?: (event: H3Event) => GenerateRegistrationOptionsOpts | Promise<GenerateRegistrationOptionsOpts>
validateUser?: (user: WebAuthnUser) => Promise<unknown>
}

export type WebAuthnAuthenticateEventHandlerOptions = WebAuthnEventHandlerBase<{
Expand Down Expand Up @@ -72,7 +75,7 @@ export interface WebAuthnComposable {
* @param user.displayName - The display name to register, used for convenience and personalization and should not be relied upon as a secure identifier for authentication processes
* @returns true if the registration was successful
*/
register: <T extends { userName: string, displayName?: string }>(data: T) => Promise<boolean>
register: <T extends WebAuthnUser>(data: T) => Promise<boolean>
/**
* Authenticate a credential
* @param userName - The user name to authenticate, can be an email address, a username, or any other form of unique ID chosen by the user
Expand Down

0 comments on commit 43ffd40

Please sign in to comment.