mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: upgrade simplewebauthn
This commit is contained in:
9 files changed
+20
-26
No files matched your search
@@ -33,7 +33,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@simplewebauthn/types": "9.0.1",
|
|
||||||
"@types/autocannon": "^7.12.6",
|
"@types/autocannon": "^7.12.6",
|
||||||
"@types/chai": "^5.0.1",
|
"@types/chai": "^5.0.1",
|
||||||
"@types/cross-spawn": "^6.0.6",
|
"@types/cross-spawn": "^6.0.6",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"@hydrooj/common": "workspace:^",
|
"@hydrooj/common": "workspace:^",
|
||||||
"@hydrooj/framework": "workspace:^",
|
"@hydrooj/framework": "workspace:^",
|
||||||
"@hydrooj/utils": "workspace:^",
|
"@hydrooj/utils": "workspace:^",
|
||||||
"@simplewebauthn/server": "9.0.3",
|
"@simplewebauthn/server": "13.1.1",
|
||||||
"@undefined-moe/require-resolve-hook": "^1.1.0",
|
"@undefined-moe/require-resolve-hook": "^1.1.0",
|
||||||
"@yarnpkg/libzip": "^3.1.0",
|
"@yarnpkg/libzip": "^3.1.0",
|
||||||
"adm-zip": "0.5.14",
|
"adm-zip": "0.5.14",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { generateRegistrationOptions, verifyRegistrationResponse } from '@simplewebauthn/server';
|
import { generateRegistrationOptions, verifyRegistrationResponse } from '@simplewebauthn/server';
|
||||||
|
import { isoBase64URL, isoUint8Array } from '@simplewebauthn/server/helpers';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import { Binary, ObjectId } from 'mongodb';
|
import { Binary, ObjectId } from 'mongodb';
|
||||||
@@ -288,12 +289,12 @@ class HomeSecurityHandler extends Handler {
|
|||||||
const options = await generateRegistrationOptions({
|
const options = await generateRegistrationOptions({
|
||||||
rpName: system.get('server.name'),
|
rpName: system.get('server.name'),
|
||||||
rpID: this.getAuthnHost(),
|
rpID: this.getAuthnHost(),
|
||||||
userID: this.user._id.toString(),
|
userID: isoUint8Array.fromUTF8String(this.user._id.toString()),
|
||||||
userDisplayName: this.user.uname,
|
userDisplayName: this.user.uname,
|
||||||
userName: `${this.user.uname}(${this.user.mail})`,
|
userName: `${this.user.uname}(${this.user.mail})`,
|
||||||
attestationType: 'direct',
|
attestationType: 'direct',
|
||||||
excludeCredentials: this.user._authenticators.map((c) => ({
|
excludeCredentials: this.user._authenticators.map((c) => ({
|
||||||
id: c.credentialID.buffer,
|
id: isoBase64URL.fromBuffer(c.credentialID.buffer),
|
||||||
type: 'public-key',
|
type: 'public-key',
|
||||||
})),
|
})),
|
||||||
authenticatorSelection: {
|
authenticatorSelection: {
|
||||||
@@ -316,12 +317,13 @@ class HomeSecurityHandler extends Handler {
|
|||||||
}).catch(() => { throw new ValidationError('verify'); });
|
}).catch(() => { throw new ValidationError('verify'); });
|
||||||
if (!verification.verified) throw new ValidationError('verify');
|
if (!verification.verified) throw new ValidationError('verify');
|
||||||
const info = verification.registrationInfo;
|
const info = verification.registrationInfo;
|
||||||
const id = Buffer.from(info.credentialID);
|
const id = isoBase64URL.toBuffer(info.credential.id);
|
||||||
if (this.user._authenticators.find((c) => c.credentialID.buffer.toString() === id.toString())) throw new ValidationError('authenticator');
|
if (this.user._authenticators.find((c) => c.credentialID.buffer.toString() === id.toString())) throw new ValidationError('authenticator');
|
||||||
this.user._authenticators.push({
|
this.user._authenticators.push({
|
||||||
...info,
|
...info,
|
||||||
|
counter: info.credential.counter,
|
||||||
credentialID: new Binary(id),
|
credentialID: new Binary(id),
|
||||||
credentialPublicKey: new Binary(Buffer.from(info.credentialPublicKey)),
|
credentialPublicKey: new Binary(Buffer.from(info.credential.publicKey)),
|
||||||
attestationObject: new Binary(Buffer.from(info.attestationObject)),
|
attestationObject: new Binary(Buffer.from(info.attestationObject)),
|
||||||
name,
|
name,
|
||||||
regat: Date.now(),
|
regat: Date.now(),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { generateAuthenticationOptions, verifyAuthenticationResponse } from '@simplewebauthn/server';
|
import { generateAuthenticationOptions, verifyAuthenticationResponse } from '@simplewebauthn/server';
|
||||||
|
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import type { Binary } from 'mongodb';
|
import type { Binary } from 'mongodb';
|
||||||
import type { Context } from '../context';
|
import type { Context } from '../context';
|
||||||
@@ -144,8 +145,7 @@ class UserWebauthnHandler extends Handler {
|
|||||||
if (!udoc.authn) throw new AuthOperationError('authn', 'disabled');
|
if (!udoc.authn) throw new AuthOperationError('authn', 'disabled');
|
||||||
const options = await generateAuthenticationOptions({
|
const options = await generateAuthenticationOptions({
|
||||||
allowCredentials: udoc._authenticators.map((authenticator) => ({
|
allowCredentials: udoc._authenticators.map((authenticator) => ({
|
||||||
id: authenticator.credentialID.buffer,
|
id: isoBase64URL.fromBuffer(authenticator.credentialID.buffer),
|
||||||
type: 'public-key',
|
|
||||||
})),
|
})),
|
||||||
rpID: this.getAuthnHost(),
|
rpID: this.getAuthnHost(),
|
||||||
userVerification: 'preferred',
|
userVerification: 'preferred',
|
||||||
@@ -169,10 +169,10 @@ class UserWebauthnHandler extends Handler {
|
|||||||
expectedChallenge: challenge,
|
expectedChallenge: challenge,
|
||||||
expectedOrigin: this.request.headers.origin,
|
expectedOrigin: this.request.headers.origin,
|
||||||
expectedRPID: this.getAuthnHost(),
|
expectedRPID: this.getAuthnHost(),
|
||||||
authenticator: {
|
credential: {
|
||||||
...authenticator,
|
...authenticator,
|
||||||
credentialID: authenticator.credentialID.buffer,
|
id: isoBase64URL.fromBuffer(authenticator.credentialID.buffer),
|
||||||
credentialPublicKey: authenticator.credentialPublicKey.buffer,
|
publicKey: authenticator.credentialPublicKey.buffer,
|
||||||
},
|
},
|
||||||
}).catch(() => null);
|
}).catch(() => null);
|
||||||
if (!verification?.verified) throw new ValidationError('authenticator');
|
if (!verification?.verified) throw new ValidationError('authenticator');
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
import type { AttestationFormat, CredentialDeviceType, } from '@simplewebauthn/server';
|
||||||
import type { AuthenticationExtensionsAuthenticatorOutputs } from '@simplewebauthn/server/esm/helpers/decodeAuthenticatorExtensions';
|
import type { AuthenticationExtensionsAuthenticatorOutputs } from '@simplewebauthn/server/esm/helpers/decodeAuthenticatorExtensions';
|
||||||
import type { AttestationFormat } from '@simplewebauthn/server/helpers';
|
|
||||||
import { CredentialDeviceType } from '@simplewebauthn/types';
|
|
||||||
import type fs from 'fs';
|
import type fs from 'fs';
|
||||||
import type { Dictionary, NumericDictionary } from 'lodash';
|
import type { Dictionary, NumericDictionary } from 'lodash';
|
||||||
import type { Binary, FindCursor, ObjectId } from 'mongodb';
|
import type { Binary, FindCursor, ObjectId } from 'mongodb';
|
||||||
|
|||||||
@@ -127,18 +127,12 @@ export class User {
|
|||||||
: doc.owner === this._id || (doc.maintainer || []).includes(this._id);
|
: doc.owner === this._id || (doc.maintainer || []).includes(this._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPerm(...perm: bigint[]) {
|
hasPerm(...perms: bigint[]) {
|
||||||
for (const i in perm) {
|
return perms.some((perm) => (this.perm & this.scope & perm) === perm);
|
||||||
if ((this.perm & this.scope & perm[i]) === perm[i]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPriv(...priv: number[]) {
|
hasPriv(...privs: number[]) {
|
||||||
for (const i in priv) {
|
return privs.some((priv) => (this.priv & priv) === priv);
|
||||||
if ((this.priv & priv[i]) === priv[i]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkPassword(password: string) {
|
async checkPassword(password: string) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
"@hydrooj/utils": "workspace:^",
|
"@hydrooj/utils": "workspace:^",
|
||||||
"@sentry/browser": "^8.54.0",
|
"@sentry/browser": "^8.54.0",
|
||||||
"@sentry/webpack-plugin": "^3.1.2",
|
"@sentry/webpack-plugin": "^3.1.2",
|
||||||
"@simplewebauthn/browser": "9.0.1",
|
"@simplewebauthn/browser": "13.1.0",
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@types/jquery": "^3.5.32",
|
"@types/jquery": "^3.5.32",
|
||||||
"@types/jquery.transit": "^0.9.33",
|
"@types/jquery.transit": "^0.9.33",
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ async function enableAuthn(type: string) {
|
|||||||
let credential;
|
let credential;
|
||||||
try {
|
try {
|
||||||
console.log(authnInfo);
|
console.log(authnInfo);
|
||||||
credential = await startRegistration(authnInfo.authOptions);
|
credential = await startRegistration({ optionsJSON: authnInfo.authOptions });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notification.error(i18n('Failed to get credential: {0}', err));
|
Notification.error(i18n('Failed to get credential: {0}', err));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ async function verifywebauthn($form) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Notification.info(i18n('Please follow the instructions on your device to complete the verification.'));
|
Notification.info(i18n('Please follow the instructions on your device to complete the verification.'));
|
||||||
const result = await startAuthentication(authnInfo.authOptions)
|
const result = await startAuthentication({ optionsJSON: authnInfo.authOptions })
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
Notification.error(i18n('Failed to get credential: {0}', e));
|
Notification.error(i18n('Failed to get credential: {0}', e));
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in new issue
Block a user