Skip to content

Commit c998ee6

Browse files
fix: don't break on Edge runtime when WebAuthn isn't used (#9919)
* require externally-defined simplewebauthn methods * import simplewebauthn in provider file * revert unnecessary changes * explicitly only import type from providers/webauthn * remove getSimpleWebAuthnBrowserScriptTag * fixes * drop @internal --------- Co-authored-by: Balázs Orbán <[email protected]>
1 parent 24669ea commit c998ee6

File tree

7 files changed

+168
-96
lines changed

7 files changed

+168
-96
lines changed

packages/core/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,14 @@
7070
"preact-render-to-string": "5.2.3"
7171
},
7272
"peerDependencies": {
73+
"@simplewebauthn/browser": "^9.0.1",
7374
"@simplewebauthn/server": "^9.0.1",
7475
"nodemailer": "^6.8.0"
7576
},
7677
"peerDependenciesMeta": {
78+
"@simplewebauthn/browser": {
79+
"optional": true
80+
},
7781
"@simplewebauthn/server": {
7882
"optional": true
7983
},
@@ -99,4 +103,4 @@
99103
"postcss": "8.4.19",
100104
"postcss-nesting": "^12.0.2"
101105
}
102-
}
106+
}

packages/core/src/lib/pages/index.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,24 @@ import type {
1414
PublicProvider,
1515
} from "../../types.js"
1616
import type { Cookie } from "../utils/cookie.js"
17-
import { getSimpleWebAuthnBrowserScriptTag } from "../../providers/webauthn.js"
1817

19-
function send({ html, title, status, cookies, theme, headTags }: any): ResponseInternal {
18+
function send({
19+
html,
20+
title,
21+
status,
22+
cookies,
23+
theme,
24+
headTags,
25+
}: any): ResponseInternal {
2026
return {
2127
cookies,
2228
status,
2329
headers: { "Content-Type": "text/html" },
2430
body: `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>${css}</style><title>${title}</title>${
2531
headTags ?? ""
26-
}</head><body class="__next-auth-theme-${theme?.colorScheme ?? "auto"}"><div class="page">${renderToString(html)}</div></body></html>`,
32+
}</head><body class="__next-auth-theme-${
33+
theme?.colorScheme ?? "auto"
34+
}"><div class="page">${renderToString(html)}</div></body></html>`,
2735
}
2836
}
2937

@@ -87,11 +95,17 @@ export default function renderPage(params: RenderPageParams) {
8795
// a simpleWebAuthnBrowserScript is defined, we need to
8896
// render the script in the page.
8997
const webauthnProvider = providers?.find(
90-
(p): p is InternalProvider<"webauthn"> => p.type === "webauthn" && p.enableConditionalUI
98+
(p): p is InternalProvider<"webauthn"> =>
99+
p.type === "webauthn" &&
100+
p.enableConditionalUI &&
101+
!!p.simpleWebAuthnBrowserVersion
91102
)
92-
const simpleWebAuthnBrowserScript = webauthnProvider ?
93-
getSimpleWebAuthnBrowserScriptTag(webauthnProvider) :
94-
undefined
103+
104+
let simpleWebAuthnBrowserScript = ""
105+
if (webauthnProvider) {
106+
const { simpleWebAuthnBrowserVersion } = webauthnProvider
107+
simpleWebAuthnBrowserScript = `<script src="https://unpkg.com/browse/@simplewebauthn/browser@${simpleWebAuthnBrowserVersion}/dist/bundle/index.umd.min.js" crossorigin="anonymous"></script>`
108+
}
95109

96110
return send({
97111
cookies,

packages/core/src/lib/utils/webauthn-utils.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import type { RelayingParty, WebAuthnProviderType } from "../../providers/webauthn";
1+
import type { WebAuthnProviderType } from "../../providers/webauthn";
22
import type { Account, Authenticator, Awaited, InternalOptions, RequestInternal, ResponseInternal, User } from "../../types";
33
import type { Cookie } from "./cookie";
44
import { AdapterError, AuthError, InvalidProvider, MissingAdapter, WebAuthnVerificationError } from "../../errors";
55
import { webauthnChallenge } from "../actions/callback/oauth/checks";
6-
import { VerifiedAuthenticationResponse, VerifiedRegistrationResponse, generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
76
import type {
87
AuthenticationResponseJSON,
98
PublicKeyCredentialCreationOptionsJSON,
@@ -13,6 +12,7 @@ import type {
1312
import type { Adapter, AdapterAccount, AdapterAuthenticator } from "../../adapters";
1413
import type { GetUserInfo } from "../../providers/webauthn";
1514
import { randomString } from "./web";
15+
import type { VerifiedAuthenticationResponse, VerifiedRegistrationResponse } from "@simplewebauthn/server";
1616

1717
export type WebAuthnRegister = "register"
1818
export type WebAuthnAuthenticate = "authenticate"
@@ -198,7 +198,7 @@ export async function verifyAuthenticate(
198198
let verification: VerifiedAuthenticationResponse
199199
try {
200200
const relayingParty = provider.getRelayingParty(options, request)
201-
verification = await verifyAuthenticationResponse({
201+
verification = await provider.simpleWebAuthn.verifyAuthenticationResponse({
202202
...provider.verifyAuthenticationOptions,
203203
expectedChallenge,
204204
response: data as AuthenticationResponseJSON,
@@ -274,7 +274,7 @@ export async function verifyRegister(
274274
let verification: VerifiedRegistrationResponse
275275
try {
276276
const relayingParty = provider.getRelayingParty(options, request)
277-
verification = await verifyRegistrationResponse({
277+
verification = await provider.simpleWebAuthn.verifyRegistrationResponse({
278278
...provider.verifyRegistrationOptions,
279279
expectedChallenge,
280280
response: data as RegistrationResponseJSON,
@@ -336,7 +336,7 @@ async function getAuthenticationOptions(options: InternalOptionsWebAuthn, reques
336336
const relayingParty = provider.getRelayingParty(options, request)
337337

338338
// Return the authentication options.
339-
return await generateAuthenticationOptions({
339+
return await provider.simpleWebAuthn.generateAuthenticationOptions({
340340
...provider.authenticationOptions,
341341
rpID: relayingParty.id,
342342
allowCredentials: authenticators?.map((a) => ({
@@ -375,7 +375,7 @@ async function getRegistrationOptions(
375375
const relayingParty = provider.getRelayingParty(options, request)
376376

377377
// Return the registration options.
378-
return await generateRegistrationOptions({
378+
return await provider.simpleWebAuthn.generateRegistrationOptions({
379379
...provider.registrationOptions,
380380
userID,
381381
userName: user.email,

0 commit comments

Comments
 (0)