Skip to content

Commit

Permalink
feat(g dbAuth): Detect WebAuthn support (#10864)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Jun 20, 2024
1 parent 60a3b1a commit 4637f61
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changesets/10864.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- feat(g dbAuth): Detect WebAuthn support (#10864) by @Tobbe

Automatically add WebAuthn support to generated pages when WebAuthn is enabled for dbAuth
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,75 @@ describe('dbAuth handler WebAuthn task title', () => {
)
})

it("does not prompt for WebAuthn if it's already set up", async () => {
const localMockFiles = { ...mockFiles }
localMockFiles[path.join(getPaths().web.src, 'auth.ts')] = `
import { createDbAuthClient, createAuth } from '@redwoodjs/auth-dbauth-web'
const dbAuthClient = createDbAuthClient()
export const { AuthProvider, useAuth } = createAuth(dbAuthClient)
`
localMockFiles[path.join(getPaths().web.base, 'package.json')] = `{
"name": "web",
"version": "0.0.0",
"private": true,
"dependencies": {
"@redwoodjs/auth-dbauth-web": "7.0.0",
"@simplewebauthn/browser": "7.4.0"
}
}
`

vol.reset()
vol.fromJSON(localMockFiles)

await dbAuth.handler({
listr2: { silentRendererCondition: true },
usernameLabel: 'email',
passwordLabel: 'password',
})

expect(mockSkippedTaskTitles[1]).toEqual(
'Querying WebAuthn addition: WebAuthn setup detected - ' +
'support will be included in pages',
)
})

it('does not prompt for WebAuthn if dbAuth is set up', async () => {
const localMockFiles = { ...mockFiles }
localMockFiles[path.join(getPaths().web.src, 'auth.ts')] = `
import { createDbAuthClient, createAuth } from '@redwoodjs/auth-dbauth-web'
const dbAuthClient = createDbAuthClient()
export const { AuthProvider, useAuth } = createAuth(dbAuthClient)
`
localMockFiles[path.join(getPaths().web.base, 'package.json')] = `{
"name": "web",
"version": "0.0.0",
"private": true,
"dependencies": {
"@redwoodjs/auth-dbauth-web": "7.0.0",
}
}
`

vol.reset()
vol.fromJSON(localMockFiles)

await dbAuth.handler({
listr2: { silentRendererCondition: true },
usernameLabel: 'email',
passwordLabel: 'password',
})

expect(mockSkippedTaskTitles[1]).toEqual(
'Querying WebAuthn addition: No WebAuthn setup detected - ' +
'support will not be included in pages',
)
})

it('is correct after prompt answer "No"', async () => {
const customEnquirer = new Enquirer({ show: false })
customEnquirer.on('prompt', (prompt) => {
Expand Down
37 changes: 37 additions & 0 deletions packages/cli/src/commands/generate/dbAuth/dbAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,20 +319,48 @@ const tasks = ({
title: 'Querying WebAuthn addition...',
task: async (ctx, task) => {
if (webauthn != null) {
// We enter here if the user passed the `--webauthn` flag. The flag
// always takes precedence.

ctx.webauthn = webauthn

task.skip(
`Querying WebAuthn addition: argument webauthn passed, WebAuthn${
webauthn ? '' : ' not'
} included`,
)
return
}

if (isDbAuthSetup()) {
if (isWebAuthnEnabled()) {
ctx.webauthn = webauthn = true

task.skip(
'Querying WebAuthn addition: WebAuthn setup detected - ' +
'support will be included in pages',
)
} else {
ctx.webauthn = webauthn = false

task.skip(
'Querying WebAuthn addition: No WebAuthn setup detected - ' +
'support will not be included in pages',
)
}

return
}

const response = await task.prompt({
type: 'confirm',
name: 'answer',
message: `Enable WebAuthn support (TouchID/FaceID) on LoginPage? See https://redwoodjs.com/docs/auth/dbAuth#webAuthn`,
default: false,
})

ctx.webauthn = webauthn = response

task.title = `Querying WebAuthn addition: WebAuthn addition${
webauthn ? '' : ' not'
} included`
Expand Down Expand Up @@ -436,3 +464,12 @@ function isDbAuthSetup() {

return false
}

function isWebAuthnEnabled() {
const webPackageJson = fs.readFileSync(
path.join(getPaths().web.base, 'package.json'),
'utf-8',
)

return webPackageJson.includes('"@simplewebauthn/browser": ')
}
1 change: 1 addition & 0 deletions packages/cli/src/lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ vi.mock('@redwoodjs/project-config', async (importOriginal) => {
functions: path.join(BASE_PATH, './api/src/functions'),
},
web: {
base: path.join(BASE_PATH, './web'),
config: path.join(BASE_PATH, './web/config'),
src: path.join(BASE_PATH, './web/src'),
generators: path.join(BASE_PATH, './web/generators'),
Expand Down

0 comments on commit 4637f61

Please sign in to comment.