diff --git a/package.json b/package.json index 1a91a098..a42196e5 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "version": "1.0.0", "license": "AGPL-3.0-only", "devDependencies": { - "@simplewebauthn/typescript-types": "^8.0.0", + "@simplewebauthn/typescript-types": "7.4.0", "@types/autocannon": "^7.12.1", "@types/cross-spawn": "^6.0.3", "@types/node": "^20.8.6", diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index dd27734b..afe0384d 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -19,7 +19,7 @@ "@aws-sdk/s3-request-presigner": "3.429.0", "@graphql-tools/schema": "^10.0.0", "@hydrooj/utils": "workspace:*", - "@simplewebauthn/server": "^8.3.2", + "@simplewebauthn/server": "7.4.0", "adm-zip": "0.5.5", "cac": "^6.7.14", "cordis": "2.8.8", diff --git a/packages/hydrooj/src/handler/home.ts b/packages/hydrooj/src/handler/home.ts index aa5a7cc9..87cf1d07 100644 --- a/packages/hydrooj/src/handler/home.ts +++ b/packages/hydrooj/src/handler/home.ts @@ -280,12 +280,17 @@ class HomeSecurityHandler extends Handler { this.back(); } + getAuthnHost() { + return system.get('authn.host') && this.request.hostname.includes(system.get('authn.host')) + ? system.get('authn.host') : this.request.hostname; + } + @requireSudo @param('type', Types.Range(['cross-platform', 'platform'])) async postRegister(domainId: string, type: 'cross-platform' | 'platform') { - const options = await generateRegistrationOptions({ + const options = generateRegistrationOptions({ rpName: system.get('server.name'), - rpID: this.request.hostname, + rpID: this.getAuthnHost(), userID: this.user._id.toString(), userDisplayName: this.user.uname, userName: `${this.user.uname}(${this.user.mail})`, @@ -310,7 +315,7 @@ class HomeSecurityHandler extends Handler { response: this.args.result, expectedChallenge: this.session.webauthnVerify, expectedOrigin: this.request.headers.origin, - expectedRPID: this.request.hostname, + expectedRPID: this.getAuthnHost(), }).catch(() => { throw new ValidationError('verify'); }); if (!verification.verified) throw new ValidationError('verify'); const info = verification.registrationInfo; diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index aa98c36d..f74534b9 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -165,16 +165,22 @@ class UserSudoHandler extends Handler { class UserWebauthnHandler extends Handler { noCheckPermView = true; + getAuthnHost() { + return system.get('authn.host') && this.request.hostname.includes(system.get('authn.host')) + ? system.get('authn.host') : this.request.hostname; + } + @param('uname', Types.Username, true) async get(domainId: string, uname: string) { const udoc = this.user._id ? this.user : ((await user.getByEmail(domainId, uname)) || await user.getByUname(domainId, uname)); if (!udoc._id) throw new UserNotFoundError(uname || 'user'); if (!udoc.authn) throw new AuthOperationError('authn', 'disabled'); - const options = await generateAuthenticationOptions({ + const options = generateAuthenticationOptions({ allowCredentials: udoc._authenticators.map((authenticator) => ({ id: authenticator.credentialID.buffer, type: 'public-key', })), + rpID: this.getAuthnHost(), userVerification: 'preferred', }); await token.add(token.TYPE_WEBAUTHN, 60, { uid: udoc._id }, options.challenge); @@ -195,7 +201,7 @@ class UserWebauthnHandler extends Handler { response: result, expectedChallenge: challenge, expectedOrigin: this.request.headers.origin, - expectedRPID: this.request.hostname, + expectedRPID: this.getAuthnHost(), authenticator: { ...authenticator, credentialID: authenticator.credentialID.buffer, diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index fb57e407..9d0f77c6 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -1,5 +1,5 @@ -import { AttestationFormat } from '@simplewebauthn/server/script/helpers/decodeAttestationObject'; -import { AuthenticationExtensionsAuthenticatorOutputs } from '@simplewebauthn/server/script/helpers/decodeAuthenticatorExtensions'; +import { AttestationFormat } from '@simplewebauthn/server/dist/helpers/decodeAttestationObject'; +import { AuthenticationExtensionsAuthenticatorOutputs } from '@simplewebauthn/server/dist/helpers/decodeAuthenticatorExtensions'; import { CredentialDeviceType } from '@simplewebauthn/typescript-types'; import type fs from 'fs'; import type { Dictionary, NumericDictionary } from 'lodash'; diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 40f5fe64..c6fb99fb 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -24,7 +24,7 @@ "@fontsource/source-code-pro": "^5.0.13", "@fontsource/ubuntu-mono": "^5.0.15", "@hydrooj/utils": "workspace:*", - "@simplewebauthn/browser": "^8.3.1", + "@simplewebauthn/browser": "7.4.0", "@svgr/webpack": "^8.1.0", "@types/gulp-if": "^0.0.34", "@types/jquery": "^3.5.22",