mirror of
https://github.com/requarks/wiki.git
synced 2026-08-26 21:27:10 -05:00
feat: passkeys (add/remove)
This commit is contained in:
@@ -344,6 +344,7 @@ export async function up (knex) {
|
||||
table.string('name').notNullable()
|
||||
table.jsonb('auth').notNullable().defaultTo('{}')
|
||||
table.jsonb('meta').notNullable().defaultTo('{}')
|
||||
table.jsonb('passkeys').notNullable().defaultTo('{}')
|
||||
table.jsonb('prefs').notNullable().defaultTo('{}')
|
||||
table.boolean('hasAvatar').notNullable().defaultTo(false)
|
||||
table.boolean('isSystem').notNullable().defaultTo(false)
|
||||
|
||||
@@ -3,6 +3,8 @@ import { generateError, generateSuccess } from '../../helpers/graph.mjs'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import ms from 'ms'
|
||||
import { DateTime } from 'luxon'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { generateRegistrationOptions, verifyRegistrationResponse } from '@simplewebauthn/server'
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
@@ -122,6 +124,52 @@ export default {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Setup TFA
|
||||
*/
|
||||
async setupTFA (obj, args, context) {
|
||||
try {
|
||||
const userId = context.req.user?.id
|
||||
if (!userId) {
|
||||
throw new Error('ERR_USER_NOT_AUTHENTICATED')
|
||||
}
|
||||
|
||||
const usr = await WIKI.db.users.query().findById(userId)
|
||||
if (!usr) {
|
||||
throw new Error('ERR_INVALID_USER')
|
||||
}
|
||||
|
||||
const str = WIKI.auth.strategies[args.strategyId]
|
||||
if (!str) {
|
||||
throw new Error('ERR_INVALID_STRATEGY')
|
||||
}
|
||||
|
||||
if (!usr.auth[args.strategyId]) {
|
||||
throw new Error('ERR_INVALID_STRATEGY')
|
||||
}
|
||||
|
||||
if (usr.auth[args.strategyId].tfaIsActive) {
|
||||
throw new Error('ERR_TFA_ALREADY_ACTIVE')
|
||||
}
|
||||
|
||||
const tfaQRImage = await usr.generateTFA(args.strategyId, args.siteId)
|
||||
const tfaToken = await WIKI.db.userKeys.generateToken({
|
||||
kind: 'tfaSetup',
|
||||
userId: usr.id,
|
||||
meta: {
|
||||
strategyId: args.strategyId
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
operation: generateSuccess('TFA setup started'),
|
||||
continuationToken: tfaToken,
|
||||
tfaQRImage
|
||||
}
|
||||
} catch (err) {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Deactivate 2FA
|
||||
*/
|
||||
@@ -164,6 +212,158 @@ export default {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Setup Passkey
|
||||
*/
|
||||
async setupPasskey (obj, args, context) {
|
||||
try {
|
||||
const userId = context.req.user?.id
|
||||
if (!userId) {
|
||||
throw new Error('ERR_USER_NOT_AUTHENTICATED')
|
||||
}
|
||||
|
||||
const usr = await WIKI.db.users.query().findById(userId)
|
||||
if (!usr) {
|
||||
throw new Error('ERR_INVALID_USER')
|
||||
}
|
||||
|
||||
const site = WIKI.sites[args.siteId]
|
||||
if (!site) {
|
||||
throw new Error('ERR_INVALID_SITE')
|
||||
} else if (site.hostname === '*') {
|
||||
WIKI.logger.warn('Cannot use passkeys with a wildcard site hostname. Enter a valid hostname under the Administration Area > General.')
|
||||
throw new Error('ERR_PK_HOSTNAME_MISSING')
|
||||
}
|
||||
|
||||
const options = await generateRegistrationOptions({
|
||||
rpName: site.config.title,
|
||||
rpId: site.hostname,
|
||||
userID: usr.id,
|
||||
userName: usr.email,
|
||||
userDisplayName: usr.name,
|
||||
attestationType: 'none',
|
||||
authenticatorSelection: {
|
||||
residentKey: 'required',
|
||||
userVerification: 'preferred'
|
||||
},
|
||||
excludeCredentials: usr.passkeys.authenticators?.map(authenticator => ({
|
||||
id: new Uint8Array(authenticator.credentialID),
|
||||
type: 'public-key',
|
||||
transports: authenticator.transports
|
||||
})) ?? []
|
||||
})
|
||||
|
||||
usr.passkeys.reg = {
|
||||
challenge: options.challenge,
|
||||
rpId: site.hostname,
|
||||
siteId: site.id
|
||||
}
|
||||
|
||||
await usr.$query().patch({
|
||||
passkeys: usr.passkeys
|
||||
})
|
||||
|
||||
return {
|
||||
operation: generateSuccess('Passkey registration options generated successfully.'),
|
||||
registrationOptions: options
|
||||
}
|
||||
} catch (err) {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Finalize Passkey Registration
|
||||
*/
|
||||
async finalizePasskey (obj, args, context) {
|
||||
try {
|
||||
const userId = context.req.user?.id
|
||||
if (!userId) {
|
||||
throw new Error('ERR_USER_NOT_AUTHENTICATED')
|
||||
}
|
||||
|
||||
const usr = await WIKI.db.users.query().findById(userId)
|
||||
if (!usr) {
|
||||
throw new Error('ERR_INVALID_USER')
|
||||
} else if (!usr.passkeys?.reg) {
|
||||
throw new Error('ERR_PASSKEY_NOT_SETUP')
|
||||
}
|
||||
|
||||
if (!args.name || args.name.trim().length < 1 || args.name.length > 255) {
|
||||
throw new Error('ERR_PK_NAME_MISSING_OR_INVALID')
|
||||
}
|
||||
|
||||
const verification = await verifyRegistrationResponse({
|
||||
response: args.registrationResponse,
|
||||
expectedChallenge: usr.passkeys.reg.challenge,
|
||||
expectedOrigin: `https://${usr.passkeys.reg.rpId}`,
|
||||
expectedRPID: usr.passkeys.reg.rpId,
|
||||
requireUserVerification: true
|
||||
})
|
||||
|
||||
if (!verification.verified) {
|
||||
throw new Error('ERR_PK_VERIFICATION_FAILED')
|
||||
}
|
||||
|
||||
if (!usr.passkeys.authenticators) {
|
||||
usr.passkeys.authenticators = []
|
||||
}
|
||||
usr.passkeys.authenticators.push({
|
||||
...verification.registrationInfo,
|
||||
id: uuid(),
|
||||
createdAt: new Date(),
|
||||
name: args.name,
|
||||
siteId: usr.passkeys.reg.siteId,
|
||||
transports: args.registrationResponse.response.transports
|
||||
})
|
||||
|
||||
delete usr.passkeys.reg
|
||||
|
||||
await usr.$query().patch({
|
||||
passkeys: JSON.stringify(usr.passkeys, (k, v) => {
|
||||
if (v instanceof Uint8Array) {
|
||||
return Array.apply([], v)
|
||||
}
|
||||
return v
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
operation: generateSuccess('Passkey registered successfully.')
|
||||
}
|
||||
} catch (err) {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Deactivate a passkey
|
||||
*/
|
||||
async deactivatePasskey (obj, args, context) {
|
||||
try {
|
||||
const userId = context.req.user?.id
|
||||
if (!userId) {
|
||||
throw new Error('ERR_USER_NOT_AUTHENTICATED')
|
||||
}
|
||||
|
||||
const usr = await WIKI.db.users.query().findById(userId)
|
||||
if (!usr) {
|
||||
throw new Error('ERR_INVALID_USER')
|
||||
} else if (!usr.passkeys?.authenticators) {
|
||||
throw new Error('ERR_PASSKEY_NOT_SETUP')
|
||||
}
|
||||
|
||||
usr.passkeys.authenticators = usr.passkeys.authenticators.filter(a => a.id !== args.id)
|
||||
|
||||
await usr.$query().patch({
|
||||
passkeys: usr.passkeys
|
||||
})
|
||||
|
||||
return {
|
||||
operation: generateSuccess('Passkey deactivated successfully.')
|
||||
}
|
||||
} catch (err) {
|
||||
return generateError(err)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Perform Password Change
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,7 @@ import { generateError, generateSuccess } from '../../helpers/graph.mjs'
|
||||
import _, { isNil } from 'lodash-es'
|
||||
import path from 'node:path'
|
||||
import fs from 'fs-extra'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
@@ -59,6 +60,13 @@ export default {
|
||||
return auth
|
||||
})
|
||||
|
||||
usr.passkeys = usr.passkeys.authenticators?.map(a => ({
|
||||
id: a.id,
|
||||
createdAt: DateTime.fromISO(a.createdAt).toJSDate(),
|
||||
name: a.name,
|
||||
siteHostname: a.rpID
|
||||
})) ?? []
|
||||
|
||||
return usr
|
||||
},
|
||||
// async profile (obj, args, context, info) {
|
||||
|
||||
@@ -41,10 +41,28 @@ extend type Mutation {
|
||||
setup: Boolean
|
||||
): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60)
|
||||
|
||||
setupTFA(
|
||||
strategyId: UUID!
|
||||
siteId: UUID!
|
||||
): AuthenticationSetupTFAResponse
|
||||
|
||||
deactivateTFA(
|
||||
strategyId: UUID!
|
||||
): DefaultResponse
|
||||
|
||||
setupPasskey(
|
||||
siteId: UUID!
|
||||
): AuthenticationSetupPasskeyResponse
|
||||
|
||||
finalizePasskey(
|
||||
registrationResponse: JSON!
|
||||
name: String!
|
||||
): DefaultResponse
|
||||
|
||||
deactivatePasskey(
|
||||
id: UUID!
|
||||
): DefaultResponse
|
||||
|
||||
changePassword(
|
||||
continuationToken: String
|
||||
currentPassword: String
|
||||
@@ -135,6 +153,17 @@ type AuthenticationTokenResponse {
|
||||
jwt: String
|
||||
}
|
||||
|
||||
type AuthenticationSetupTFAResponse {
|
||||
operation: Operation
|
||||
continuationToken: String
|
||||
tfaQRImage: String
|
||||
}
|
||||
|
||||
type AuthenticationSetupPasskeyResponse {
|
||||
operation: Operation
|
||||
registrationOptions: JSON
|
||||
}
|
||||
|
||||
input AuthenticationStrategyInput {
|
||||
key: String!
|
||||
strategyKey: String!
|
||||
|
||||
@@ -132,6 +132,7 @@ type User {
|
||||
name: String
|
||||
email: String
|
||||
auth: [UserAuth]
|
||||
passkeys: [UserPasskey]
|
||||
hasAvatar: Boolean
|
||||
isSystem: Boolean
|
||||
isActive: Boolean
|
||||
@@ -152,6 +153,13 @@ type UserAuth {
|
||||
config: JSON
|
||||
}
|
||||
|
||||
type UserPasskey {
|
||||
id: UUID
|
||||
name: String
|
||||
createdAt: Date
|
||||
siteHostname: String
|
||||
}
|
||||
|
||||
type UserDefaults {
|
||||
timezone: String
|
||||
dateFormat: String
|
||||
|
||||
@@ -1613,6 +1613,9 @@
|
||||
"editor.unsaved.body": "You have unsaved changes. Are you sure you want to leave the editor and discard any modifications you made since the last save?",
|
||||
"editor.unsaved.title": "Discard Unsaved Changes?",
|
||||
"editor.unsavedWarning": "You have unsaved edits. Are you sure you want to leave the editor?",
|
||||
"error.ERR_PK_ALREADY_REGISTERED": "It looks like this authenticator is already registered.",
|
||||
"error.ERR_PK_HOSTNAME_MISSING": "Your administrator must set a valid site hostname before passkeys can be used.",
|
||||
"error.ERR_PK_USER_CANCELLED": "Passkey registration aborted. Make sure to remove the key from your device.",
|
||||
"fileman.7zFileType": "7zip Archive",
|
||||
"fileman.aacFileType": "AAC Audio File",
|
||||
"fileman.aiFileType": "Adobe Illustrator Document",
|
||||
@@ -1755,6 +1758,7 @@
|
||||
"profile.authLoadingFailed": "Failed to load authentication methods.",
|
||||
"profile.authModifyTfa": "Modify 2FA",
|
||||
"profile.authSetTfa": "Set 2FA",
|
||||
"profile.authSetTfaLoading": "Setting up 2FA... Please wait",
|
||||
"profile.avatar": "Avatar",
|
||||
"profile.avatarClearFailed": "Failed to clear profile picture.",
|
||||
"profile.avatarClearSuccess": "Profile picture cleared successfully.",
|
||||
@@ -1798,6 +1802,18 @@
|
||||
"profile.pages.refreshSuccess": "Page list has been refreshed.",
|
||||
"profile.pages.subtitle": "List of pages I created or last modified",
|
||||
"profile.pages.title": "Pages",
|
||||
"profile.passkeys": "Passkeys",
|
||||
"profile.passkeysAdd": "Add Passkey",
|
||||
"profile.passkeysDeactivateConfirm": "Are you sure you want to deactivate this passkey?",
|
||||
"profile.passkeysDeactivateFailed": "Failed to deactivate the passkey.",
|
||||
"profile.passkeysDeactivateSuccess": "Passkey deactivated successfully. You may still need to remove the passkey from your device.",
|
||||
"profile.passkeysIntro": "Passkeys are a replacement for passwords for a faster, easier and more secure login. It relies on your device existing biometrics (phone, computer, security key) to validate your identity.",
|
||||
"profile.passkeysInvalidName": "Passkey name is missing or invalid.",
|
||||
"profile.passkeysName": "Passkey Name",
|
||||
"profile.passkeysNameHint": "Enter a name for your passkey:",
|
||||
"profile.passkeysSetupFailed": "Failed to setup new passkey.",
|
||||
"profile.passkeysSetupSuccess": "Passkey registered successfully.",
|
||||
"profile.passkeysUnsupported": "Passkeys are not supported on your device.",
|
||||
"profile.preferences": "Preferences",
|
||||
"profile.pronouns": "Pronouns",
|
||||
"profile.pronounsHint": "Let people know which pronouns should they use when referring to you.",
|
||||
|
||||
@@ -74,7 +74,7 @@ export class User extends Model {
|
||||
|
||||
async generateTFA(strategyId, siteId) {
|
||||
WIKI.logger.debug(`Generating new TFA secret for user ${this.id}...`)
|
||||
const site = WIKI.sites[siteId] ?? WIKI.sites[0] ?? { config: { title: 'Wiki' }}
|
||||
const site = WIKI.sites[siteId] ?? WIKI.sites[0] ?? { config: { title: 'Wiki' } }
|
||||
const tfaInfo = tfa.generateSecret({
|
||||
name: site.config.title,
|
||||
account: this.email
|
||||
@@ -485,7 +485,7 @@ export class User extends Model {
|
||||
}
|
||||
|
||||
if (user) {
|
||||
user.auth[strategyId].password = await bcrypt.hash(newPassword, 12),
|
||||
user.auth[strategyId].password = await bcrypt.hash(newPassword, 12)
|
||||
user.auth[strategyId].mustChangePwd = false
|
||||
await user.$query().patch({
|
||||
auth: user.auth
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
const request = require('request-promise')
|
||||
// TODO: refactor to use fetch()
|
||||
|
||||
const prefetch = async (element) => {
|
||||
const url = element.attr(`src`)
|
||||
let response
|
||||
try {
|
||||
response = await request({
|
||||
method: `GET`,
|
||||
url,
|
||||
resolveWithFullResponse: true
|
||||
})
|
||||
} catch (err) {
|
||||
WIKI.logger.warn(`Failed to prefetch ${url}`)
|
||||
WIKI.logger.warn(err)
|
||||
return
|
||||
}
|
||||
const contentType = response.headers[`content-type`]
|
||||
const image = Buffer.from(response.body).toString('base64')
|
||||
element.attr('src', `data:${contentType};base64,${image}`)
|
||||
element.removeClass('prefetch-candidate')
|
||||
}
|
||||
// const prefetch = async (element) => {
|
||||
// const url = element.attr(`src`)
|
||||
// let response
|
||||
// try {
|
||||
// response = await request({
|
||||
// method: `GET`,
|
||||
// url,
|
||||
// resolveWithFullResponse: true
|
||||
// })
|
||||
// } catch (err) {
|
||||
// WIKI.logger.warn(`Failed to prefetch ${url}`)
|
||||
// WIKI.logger.warn(err)
|
||||
// return
|
||||
// }
|
||||
// const contentType = response.headers[`content-type`]
|
||||
// const image = Buffer.from(response.body).toString('base64')
|
||||
// element.attr('src', `data:${contentType};base64,${image}`)
|
||||
// element.removeClass('prefetch-candidate')
|
||||
// }
|
||||
|
||||
module.exports = {
|
||||
async init($) {
|
||||
const promises = $('img.prefetch-candidate').map((index, element) => {
|
||||
return prefetch($(element))
|
||||
}).toArray()
|
||||
await Promise.all(promises)
|
||||
// const promises = $('img.prefetch-candidate').map((index, element) => {
|
||||
// return prefetch($(element))
|
||||
// }).toArray()
|
||||
// await Promise.all(promises)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -42,9 +42,11 @@
|
||||
"@graphql-tools/schema": "10.0.0",
|
||||
"@graphql-tools/utils": "10.0.6",
|
||||
"@joplin/turndown-plugin-gfm": "1.0.50",
|
||||
"@node-saml/passport-saml": "4.0.4",
|
||||
"@root/csr": "0.8.1",
|
||||
"@root/keypairs": "0.10.3",
|
||||
"@root/pem": "1.0.4",
|
||||
"@simplewebauthn/server": "8.2.0",
|
||||
"acme": "3.0.3",
|
||||
"akismet-api": "6.0.0",
|
||||
"aws-sdk": "2.1472.0",
|
||||
@@ -83,8 +85,6 @@
|
||||
"graphql-upload": "16.0.2",
|
||||
"he": "1.2.0",
|
||||
"highlight.js": "11.8.0",
|
||||
"i18next": "23.5.1",
|
||||
"i18next-node-fs-backend": "2.1.3",
|
||||
"image-size": "1.0.2",
|
||||
"js-base64": "3.7.5",
|
||||
"js-binary": "1.2.0",
|
||||
@@ -138,7 +138,6 @@
|
||||
"passport-oauth2": "1.7.0",
|
||||
"passport-okta-oauth": "0.0.1",
|
||||
"passport-openidconnect": "0.1.1",
|
||||
"passport-saml": "3.2.4",
|
||||
"passport-slack-oauth2": "1.2.0",
|
||||
"passport-twitch-strategy": "2.2.0",
|
||||
"pem-jwk": "2.0.0",
|
||||
@@ -152,8 +151,6 @@
|
||||
"puppeteer-core": "21.3.8",
|
||||
"qr-image": "3.2.0",
|
||||
"remove-markdown": "0.5.0",
|
||||
"request": "2.88.2",
|
||||
"request-promise": "4.2.6",
|
||||
"safe-regex": "2.1.1",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"scim-query-filter-parser": "2.0.4",
|
||||
@@ -179,7 +176,6 @@
|
||||
"eslint-plugin-import": "2.28.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
"eslint-plugin-standard": "5.0.0",
|
||||
"nodemon": "3.0.1"
|
||||
},
|
||||
"overrides": {
|
||||
|
||||
Generated
+265
-313
@@ -23,6 +23,9 @@ dependencies:
|
||||
'@joplin/turndown-plugin-gfm':
|
||||
specifier: 1.0.50
|
||||
version: 1.0.50
|
||||
'@node-saml/passport-saml':
|
||||
specifier: 4.0.4
|
||||
version: 4.0.4
|
||||
'@root/csr':
|
||||
specifier: 0.8.1
|
||||
version: 0.8.1
|
||||
@@ -32,6 +35,9 @@ dependencies:
|
||||
'@root/pem':
|
||||
specifier: 1.0.4
|
||||
version: 1.0.4
|
||||
'@simplewebauthn/server':
|
||||
specifier: 8.2.0
|
||||
version: 8.2.0
|
||||
acme:
|
||||
specifier: 3.0.3
|
||||
version: 3.0.3
|
||||
@@ -146,12 +152,6 @@ dependencies:
|
||||
highlight.js:
|
||||
specifier: 11.8.0
|
||||
version: 11.8.0
|
||||
i18next:
|
||||
specifier: 23.5.1
|
||||
version: 23.5.1
|
||||
i18next-node-fs-backend:
|
||||
specifier: 2.1.3
|
||||
version: 2.1.3
|
||||
image-size:
|
||||
specifier: 1.0.2
|
||||
version: 1.0.2
|
||||
@@ -311,9 +311,6 @@ dependencies:
|
||||
passport-openidconnect:
|
||||
specifier: 0.1.1
|
||||
version: 0.1.1
|
||||
passport-saml:
|
||||
specifier: 3.2.4
|
||||
version: 3.2.4
|
||||
passport-slack-oauth2:
|
||||
specifier: 1.2.0
|
||||
version: 1.2.0
|
||||
@@ -353,12 +350,6 @@ dependencies:
|
||||
remove-markdown:
|
||||
specifier: 0.5.0
|
||||
version: 0.5.0
|
||||
request:
|
||||
specifier: 2.88.2
|
||||
version: 2.88.2
|
||||
request-promise:
|
||||
specifier: 4.2.6
|
||||
version: 4.2.6(request@2.88.2)
|
||||
safe-regex:
|
||||
specifier: 2.1.1
|
||||
version: 2.1.1
|
||||
@@ -430,9 +421,6 @@ devDependencies:
|
||||
eslint-plugin-promise:
|
||||
specifier: 6.1.1
|
||||
version: 6.1.1(eslint@8.51.0)
|
||||
eslint-plugin-standard:
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.51.0)
|
||||
nodemon:
|
||||
specifier: 3.0.1
|
||||
version: 3.0.1
|
||||
@@ -754,12 +742,53 @@ packages:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@babel/runtime@7.23.1:
|
||||
resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.0
|
||||
/@cbor-extract/cbor-extract-darwin-arm64@2.1.1:
|
||||
resolution: {integrity: sha512-blVBy5MXz6m36Vx0DfLd7PChOQKEs8lK2bD1WJn/vVgG4FXZiZmZb2GECHFvVPA5T7OnODd9xZiL3nMCv6QUhA==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@cbor-extract/cbor-extract-darwin-x64@2.1.1:
|
||||
resolution: {integrity: sha512-h6KFOzqk8jXTvkOftyRIWGrd7sKQzQv2jVdTL9nKSf3D2drCvQB/LHUxAOpPXo3pv2clDtKs3xnHalpEh3rDsw==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@cbor-extract/cbor-extract-linux-arm64@2.1.1:
|
||||
resolution: {integrity: sha512-SxAaRcYf8S0QHaMc7gvRSiTSr7nUYMqbUdErBEu+HYA4Q6UNydx1VwFE68hGcp1qvxcy9yT5U7gA+a5XikfwSQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@cbor-extract/cbor-extract-linux-arm@2.1.1:
|
||||
resolution: {integrity: sha512-ds0uikdcIGUjPyraV4oJqyVE5gl/qYBpa/Wnh6l6xLE2lj/hwnjT2XcZCChdXwW/YFZ1LUHs6waoYN8PmK0nKQ==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@cbor-extract/cbor-extract-linux-x64@2.1.1:
|
||||
resolution: {integrity: sha512-GVK+8fNIE9lJQHAlhOROYiI0Yd4bAZ4u++C2ZjlkS3YmO6hi+FUxe6Dqm+OKWTcMpL/l71N6CQAmaRcb4zyJuA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@cbor-extract/cbor-extract-win32-x64@2.1.1:
|
||||
resolution: {integrity: sha512-2Niq1C41dCRIDeD8LddiH+mxGlO7HJ612Ll3D/E73ZWBmycued+8ghTr/Ho3CMOWPUEr08XtyBMVXAjqF+TcKw==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.51.0):
|
||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||
@@ -880,6 +909,10 @@ packages:
|
||||
graphql: 16.8.1
|
||||
dev: false
|
||||
|
||||
/@hexagon/base64@1.1.28:
|
||||
resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array@0.11.11:
|
||||
resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
@@ -920,6 +953,39 @@ packages:
|
||||
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
|
||||
dev: false
|
||||
|
||||
/@node-saml/node-saml@4.0.5:
|
||||
resolution: {integrity: sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@types/debug': 4.1.9
|
||||
'@types/passport': 1.0.13
|
||||
'@types/xml-crypto': 1.4.3
|
||||
'@types/xml-encryption': 1.2.2
|
||||
'@types/xml2js': 0.4.12
|
||||
'@xmldom/xmldom': 0.8.10
|
||||
debug: 4.3.4
|
||||
xml-crypto: 3.2.0
|
||||
xml-encryption: 3.0.2
|
||||
xml2js: 0.5.0
|
||||
xmlbuilder: 15.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@node-saml/passport-saml@4.0.4:
|
||||
resolution: {integrity: sha512-xFw3gw0yo+K1mzlkW15NeBF7cVpRHN/4vpjmBKzov5YFImCWh/G0LcTZ8krH3yk2/eRPc3Or8LRPudVJBjmYaw==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@node-saml/node-saml': 4.0.5
|
||||
'@types/express': 4.17.18
|
||||
'@types/passport': 1.0.13
|
||||
'@types/passport-strategy': 0.2.36
|
||||
passport: 0.6.0
|
||||
passport-strategy: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -1194,6 +1260,50 @@ packages:
|
||||
engines: {node: '>=8.0.0'}
|
||||
dev: false
|
||||
|
||||
/@peculiar/asn1-android@2.3.6:
|
||||
resolution: {integrity: sha512-zkYh4DsiRhiNfg6tWaUuRc+huwlb9XJbmeZLrjTz9v76UK1Ehq3EnfJFED6P3sdznW/nqWe46LoM9JrqxcD58g==}
|
||||
dependencies:
|
||||
'@peculiar/asn1-schema': 2.3.6
|
||||
asn1js: 3.0.5
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@peculiar/asn1-ecc@2.3.6:
|
||||
resolution: {integrity: sha512-Hu1xzMJQWv8/GvzOiinaE6XiD1/kEhq2C/V89UEoWeZ2fLUcGNIvMxOr/pMyL0OmpRWj/mhCTXOZp4PP+a0aTg==}
|
||||
dependencies:
|
||||
'@peculiar/asn1-schema': 2.3.6
|
||||
'@peculiar/asn1-x509': 2.3.6
|
||||
asn1js: 3.0.5
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@peculiar/asn1-rsa@2.3.6:
|
||||
resolution: {integrity: sha512-DswjJyAXZnvESuImGNTvbNKvh1XApBVqU+r3UmrFFTAI23gv62byl0f5OFKWTNhCf66WQrd3sklpsCZc/4+jwA==}
|
||||
dependencies:
|
||||
'@peculiar/asn1-schema': 2.3.6
|
||||
'@peculiar/asn1-x509': 2.3.6
|
||||
asn1js: 3.0.5
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@peculiar/asn1-schema@2.3.6:
|
||||
resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==}
|
||||
dependencies:
|
||||
asn1js: 3.0.5
|
||||
pvtsutils: 1.3.5
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@peculiar/asn1-x509@2.3.6:
|
||||
resolution: {integrity: sha512-dRwX31R1lcbIdzbztiMvLNTDoGptxdV7HocNx87LfKU0fEWh7fTWJjx4oV+glETSy6heF/hJHB2J4RGB3vVSYg==}
|
||||
dependencies:
|
||||
'@peculiar/asn1-schema': 2.3.6
|
||||
asn1js: 3.0.5
|
||||
ipaddr.js: 2.1.0
|
||||
pvtsutils: 1.3.5
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@protobufjs/aspromise@1.1.2:
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
dev: false
|
||||
@@ -1306,6 +1416,27 @@ packages:
|
||||
'@root/encoding': 1.0.1
|
||||
dev: false
|
||||
|
||||
/@simplewebauthn/server@8.2.0:
|
||||
resolution: {integrity: sha512-nknf7kCa5V61Kk2zn1vTuKeAlyut9aWduIcbHNQWpMCEJqH/m8cXpb+9UV42MEQRIk8JVC1GSNeEx56QVTfJHw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
dependencies:
|
||||
'@hexagon/base64': 1.1.28
|
||||
'@peculiar/asn1-android': 2.3.6
|
||||
'@peculiar/asn1-ecc': 2.3.6
|
||||
'@peculiar/asn1-rsa': 2.3.6
|
||||
'@peculiar/asn1-schema': 2.3.6
|
||||
'@peculiar/asn1-x509': 2.3.6
|
||||
'@simplewebauthn/typescript-types': 8.0.0
|
||||
cbor-x: 1.5.4
|
||||
cross-fetch: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@simplewebauthn/typescript-types@8.0.0:
|
||||
resolution: {integrity: sha512-d7Izb2H+LZJteXMkS8DmpAarD6mZdpIOu/av/yH4/u/3Pd6DKFLyBM3j8BMmUvUqpzvJvHARNrRfQYto58mtTQ==}
|
||||
dev: false
|
||||
|
||||
/@socket.io/component-emitter@3.1.0:
|
||||
resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==}
|
||||
dev: false
|
||||
@@ -1360,6 +1491,12 @@ packages:
|
||||
'@types/node': 20.8.3
|
||||
dev: false
|
||||
|
||||
/@types/debug@4.1.9:
|
||||
resolution: {integrity: sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==}
|
||||
dependencies:
|
||||
'@types/ms': 0.7.32
|
||||
dev: false
|
||||
|
||||
/@types/express-serve-static-core@4.17.37:
|
||||
resolution: {integrity: sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==}
|
||||
dependencies:
|
||||
@@ -1425,6 +1562,10 @@ packages:
|
||||
resolution: {integrity: sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ==}
|
||||
dev: false
|
||||
|
||||
/@types/ms@0.7.32:
|
||||
resolution: {integrity: sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==}
|
||||
dev: false
|
||||
|
||||
/@types/node-fetch@2.6.6:
|
||||
resolution: {integrity: sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==}
|
||||
dependencies:
|
||||
@@ -1446,6 +1587,19 @@ packages:
|
||||
resolution: {integrity: sha512-STkyj0IQkgbmohF1afXQN64KucE3w7EgSbNJxqkJoq0KHVBV4nU5Pyku+TM9UCiCLXhZlkEFd8zq38P8lDFi6g==}
|
||||
dev: false
|
||||
|
||||
/@types/passport-strategy@0.2.36:
|
||||
resolution: {integrity: sha512-hotVZuaCt04LJYXfZD5B+5UeCcRVG8IjKaLLGTJ1eFp0wiFQA2XfsqslGGInWje+OysNNLPH/ducce5GXHDC1Q==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.18
|
||||
'@types/passport': 1.0.13
|
||||
dev: false
|
||||
|
||||
/@types/passport@1.0.13:
|
||||
resolution: {integrity: sha512-XXURryL+EZAWtbQFOHX1eNB+RJwz5XMPPz1xrGpEKr2xUZCXM4NCPkHMtZQ3B2tTSG/1IRaAcTHjczRA4sSFCw==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.18
|
||||
dev: false
|
||||
|
||||
/@types/qs@6.9.8:
|
||||
resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==}
|
||||
dev: false
|
||||
@@ -1475,6 +1629,25 @@ packages:
|
||||
'@types/node': 20.8.3
|
||||
dev: false
|
||||
|
||||
/@types/xml-crypto@1.4.3:
|
||||
resolution: {integrity: sha512-pnvKYb7vUsUIMc+C6JM/j779YWQgOMcwjnqHJ9cdaWXwWEBE1hAqthzeszRx62V5RWMvS+XS9w9tXMOYyUc8zg==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.3
|
||||
xpath: 0.0.27
|
||||
dev: false
|
||||
|
||||
/@types/xml-encryption@1.2.2:
|
||||
resolution: {integrity: sha512-UeuYOqW3ZzUQfwb/mb3GNZ2/DlVdh5mjJNmB/yFXgQr8/pwlVJ9I2w+AHPfRDzLshe7YpgUB4T1//qgbk6U87Q==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.3
|
||||
dev: false
|
||||
|
||||
/@types/xml2js@0.4.12:
|
||||
resolution: {integrity: sha512-CZPpQKBZ8db66EP5hCjwvYrLThgZvnyZrPXK2W+UI1oOaWezGt34iOaUCX4Jah2X8+rQqjvl9VKEIT8TR1I0rA==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.3
|
||||
dev: false
|
||||
|
||||
/@types/yauzl@2.10.1:
|
||||
resolution: {integrity: sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==}
|
||||
requiresBuild: true
|
||||
@@ -1519,8 +1692,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@xmldom/xmldom@0.7.13:
|
||||
resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==}
|
||||
/@xmldom/xmldom@0.8.10:
|
||||
resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dev: false
|
||||
|
||||
@@ -1607,6 +1780,7 @@ packages:
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
dev: true
|
||||
|
||||
/ajv@8.12.0:
|
||||
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
|
||||
@@ -1658,12 +1832,6 @@ packages:
|
||||
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
|
||||
dev: false
|
||||
|
||||
/argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
dependencies:
|
||||
sprintf-js: 1.0.3
|
||||
dev: false
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
@@ -1752,6 +1920,15 @@ packages:
|
||||
safer-buffer: 2.1.2
|
||||
dev: false
|
||||
|
||||
/asn1js@3.0.5:
|
||||
resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
dependencies:
|
||||
pvtsutils: 1.3.5
|
||||
pvutils: 1.1.3
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/assert-plus@1.0.0:
|
||||
resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -1802,14 +1979,6 @@ packages:
|
||||
xml2js: 0.5.0
|
||||
dev: false
|
||||
|
||||
/aws-sign2@0.7.0:
|
||||
resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
|
||||
dev: false
|
||||
|
||||
/aws4@1.12.0:
|
||||
resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==}
|
||||
dev: false
|
||||
|
||||
/axios@0.27.2:
|
||||
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
|
||||
dependencies:
|
||||
@@ -1852,12 +2021,6 @@ packages:
|
||||
engines: {node: '>=10.0.0'}
|
||||
dev: false
|
||||
|
||||
/bcrypt-pbkdf@1.0.2:
|
||||
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
|
||||
dependencies:
|
||||
tweetnacl: 0.14.5
|
||||
dev: false
|
||||
|
||||
/bcryptjs@2.4.3:
|
||||
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
|
||||
dev: false
|
||||
@@ -2042,8 +2205,26 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/caseless@0.12.0:
|
||||
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
|
||||
/cbor-extract@2.1.1:
|
||||
resolution: {integrity: sha512-1UX977+L+zOJHsp0mWFG13GLwO6ucKgSmSW6JTl8B9GUvACvHeIVpFqhU92299Z6PfD09aTXDell5p+lp1rUFA==}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-gyp-build-optional-packages: 5.0.3
|
||||
optionalDependencies:
|
||||
'@cbor-extract/cbor-extract-darwin-arm64': 2.1.1
|
||||
'@cbor-extract/cbor-extract-darwin-x64': 2.1.1
|
||||
'@cbor-extract/cbor-extract-linux-arm': 2.1.1
|
||||
'@cbor-extract/cbor-extract-linux-arm64': 2.1.1
|
||||
'@cbor-extract/cbor-extract-linux-x64': 2.1.1
|
||||
'@cbor-extract/cbor-extract-win32-x64': 2.1.1
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/cbor-x@1.5.4:
|
||||
resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==}
|
||||
optionalDependencies:
|
||||
cbor-extract: 2.1.1
|
||||
dev: false
|
||||
|
||||
/chalk@4.1.2:
|
||||
@@ -2367,13 +2548,6 @@ packages:
|
||||
resolution: {integrity: sha512-YOrdiS4b/ItbPAtyEIpkhqryoul2Bu8vtX+SN2nmxsqPnqAfh48Nu9p6zdTp9iCgCoSb6Ib8B0y4UUznaVXgtA==}
|
||||
dev: false
|
||||
|
||||
/dashdash@1.14.1:
|
||||
resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
|
||||
engines: {node: '>=0.10'}
|
||||
dependencies:
|
||||
assert-plus: 1.0.0
|
||||
dev: false
|
||||
|
||||
/data-uri-to-buffer@6.0.1:
|
||||
resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -2602,13 +2776,6 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/ecc-jsbn@0.1.2:
|
||||
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
|
||||
dependencies:
|
||||
jsbn: 0.1.1
|
||||
safer-buffer: 2.1.2
|
||||
dev: false
|
||||
|
||||
/ecdsa-sig-formatter@1.0.11:
|
||||
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
|
||||
dependencies:
|
||||
@@ -3150,10 +3317,6 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/extend@3.0.2:
|
||||
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
||||
dev: false
|
||||
|
||||
/extract-zip@2.0.1:
|
||||
resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
|
||||
engines: {node: '>= 10.17.0'}
|
||||
@@ -3187,6 +3350,7 @@ packages:
|
||||
|
||||
/fast-json-stable-stringify@2.1.0:
|
||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||
dev: true
|
||||
|
||||
/fast-levenshtein@2.0.6:
|
||||
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
|
||||
@@ -3286,19 +3450,6 @@ packages:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
/forever-agent@0.6.1:
|
||||
resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
|
||||
dev: false
|
||||
|
||||
/form-data@2.3.3:
|
||||
resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
|
||||
engines: {node: '>= 0.12'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -3443,12 +3594,6 @@ packages:
|
||||
async: 3.2.4
|
||||
dev: false
|
||||
|
||||
/getpass@0.1.7:
|
||||
resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==}
|
||||
dependencies:
|
||||
assert-plus: 1.0.0
|
||||
dev: false
|
||||
|
||||
/github-from-package@0.0.0:
|
||||
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||
dev: false
|
||||
@@ -3595,20 +3740,6 @@ packages:
|
||||
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
||||
dev: false
|
||||
|
||||
/har-schema@2.0.0:
|
||||
resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/har-validator@5.1.5:
|
||||
resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
|
||||
engines: {node: '>=6'}
|
||||
deprecated: this library is no longer supported
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
har-schema: 2.0.0
|
||||
dev: false
|
||||
|
||||
/has-bigints@1.0.2:
|
||||
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
|
||||
dev: true
|
||||
@@ -3726,15 +3857,6 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/http-signature@1.2.0:
|
||||
resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==}
|
||||
engines: {node: '>=0.8', npm: '>=1.3.7'}
|
||||
dependencies:
|
||||
assert-plus: 1.0.0
|
||||
jsprim: 1.4.2
|
||||
sshpk: 1.17.0
|
||||
dev: false
|
||||
|
||||
/https-proxy-agent@5.0.1:
|
||||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -3755,20 +3877,6 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/i18next-node-fs-backend@2.1.3:
|
||||
resolution: {integrity: sha512-CreMFiVl3ChlMc5ys/e0QfuLFOZyFcL40Jj6jaKD6DxZ/GCUMxPI9BpU43QMWUgC7r+PClpxg2cGXAl0CjG04g==}
|
||||
deprecated: replaced by i18next-fs-backend
|
||||
dependencies:
|
||||
js-yaml: 3.13.1
|
||||
json5: 2.0.0
|
||||
dev: false
|
||||
|
||||
/i18next@23.5.1:
|
||||
resolution: {integrity: sha512-JelYzcaCoFDaa+Ysbfz2JsGAKkrHiMG6S61+HLBUEIPaF40WMwW9hCPymlQGrP+wWawKxKPuSuD71WZscCsWHg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.1
|
||||
dev: false
|
||||
|
||||
/iconv-lite@0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -3866,6 +3974,11 @@ packages:
|
||||
engines: {node: '>= 0.10'}
|
||||
dev: false
|
||||
|
||||
/ipaddr.js@2.1.0:
|
||||
resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==}
|
||||
engines: {node: '>= 10'}
|
||||
dev: false
|
||||
|
||||
/is-arguments@1.1.1:
|
||||
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -4008,10 +4121,6 @@ packages:
|
||||
dependencies:
|
||||
which-typed-array: 1.1.11
|
||||
|
||||
/is-typedarray@1.0.0:
|
||||
resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
|
||||
dev: false
|
||||
|
||||
/is-weakref@1.0.2:
|
||||
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
|
||||
dependencies:
|
||||
@@ -4030,10 +4139,6 @@ packages:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
|
||||
/isstream@0.1.2:
|
||||
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
|
||||
dev: false
|
||||
|
||||
/jmespath@0.16.0:
|
||||
resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
@@ -4054,24 +4159,12 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/js-yaml@3.13.1:
|
||||
resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 1.0.10
|
||||
esprima: 4.0.1
|
||||
dev: false
|
||||
|
||||
/js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
/jsbn@0.1.1:
|
||||
resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
|
||||
dev: false
|
||||
|
||||
/jsdom@22.1.0:
|
||||
resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==}
|
||||
engines: {node: '>=16'}
|
||||
@@ -4116,23 +4209,16 @@ packages:
|
||||
|
||||
/json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
dev: true
|
||||
|
||||
/json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
dev: false
|
||||
|
||||
/json-schema@0.4.0:
|
||||
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
|
||||
dev: false
|
||||
|
||||
/json-stable-stringify-without-jsonify@1.0.1:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
dev: true
|
||||
|
||||
/json-stringify-safe@5.0.1:
|
||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||
dev: false
|
||||
|
||||
/json5@1.0.2:
|
||||
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
|
||||
hasBin: true
|
||||
@@ -4140,14 +4226,6 @@ packages:
|
||||
minimist: 1.2.8
|
||||
dev: true
|
||||
|
||||
/json5@2.0.0:
|
||||
resolution: {integrity: sha512-0EdQvHuLm7yJ7lyG5dp7Q3X2ku++BG5ZHaJ5FTnaXpKqDrw4pMxel5Bt3oAYMthnrthFBdnZ1FcsXTPyrQlV0w==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
dev: false
|
||||
|
||||
/jsonfile@4.0.0:
|
||||
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
|
||||
optionalDependencies:
|
||||
@@ -4186,16 +4264,6 @@ packages:
|
||||
semver: 7.5.4
|
||||
dev: false
|
||||
|
||||
/jsprim@1.4.2:
|
||||
resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
|
||||
engines: {node: '>=0.6.0'}
|
||||
dependencies:
|
||||
assert-plus: 1.0.0
|
||||
extsprintf: 1.3.0
|
||||
json-schema: 0.4.0
|
||||
verror: 1.10.0
|
||||
dev: false
|
||||
|
||||
/jwa@1.4.1:
|
||||
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
|
||||
dependencies:
|
||||
@@ -4763,6 +4831,13 @@ packages:
|
||||
engines: {node: '>= 6.13.0'}
|
||||
dev: false
|
||||
|
||||
/node-gyp-build-optional-packages@5.0.3:
|
||||
resolution: {integrity: sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/node-jose@2.2.0:
|
||||
resolution: {integrity: sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==}
|
||||
dependencies:
|
||||
@@ -4829,10 +4904,6 @@ packages:
|
||||
resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==}
|
||||
dev: false
|
||||
|
||||
/oauth-sign@0.9.0:
|
||||
resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
|
||||
dev: false
|
||||
|
||||
/oauth@0.9.15:
|
||||
resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==}
|
||||
dev: false
|
||||
@@ -5194,22 +5265,6 @@ packages:
|
||||
passport-strategy: 1.0.0
|
||||
dev: false
|
||||
|
||||
/passport-saml@3.2.4:
|
||||
resolution: {integrity: sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA==}
|
||||
engines: {node: '>= 12'}
|
||||
deprecated: For versions >= 4, please use scopped package @node-saml/passport-saml
|
||||
dependencies:
|
||||
'@xmldom/xmldom': 0.7.13
|
||||
debug: 4.3.4
|
||||
passport-strategy: 1.0.0
|
||||
xml-crypto: 2.1.5
|
||||
xml-encryption: 2.0.0
|
||||
xml2js: 0.4.23
|
||||
xmlbuilder: 15.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/passport-slack-oauth2@1.2.0:
|
||||
resolution: {integrity: sha512-SeQl8uPoi4ajhzgIvwQM7gW/6yPrKH0hPFjxcP/426SOZ0M9ZNDOfSa32q3NTw7KcwYOTjyWX/2xdJndQE7Rkg==}
|
||||
dependencies:
|
||||
@@ -5281,10 +5336,6 @@ packages:
|
||||
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
||||
dev: false
|
||||
|
||||
/performance-now@2.1.0:
|
||||
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
||||
dev: false
|
||||
|
||||
/pg-cloudflare@1.1.1:
|
||||
resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
|
||||
requiresBuild: true
|
||||
@@ -5579,6 +5630,17 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/pvtsutils@1.3.5:
|
||||
resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/pvutils@1.1.3:
|
||||
resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/qr-image@3.2.0:
|
||||
resolution: {integrity: sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==}
|
||||
dev: false
|
||||
@@ -5597,11 +5659,6 @@ packages:
|
||||
side-channel: 1.0.4
|
||||
dev: false
|
||||
|
||||
/qs@6.5.3:
|
||||
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
||||
engines: {node: '>=0.6'}
|
||||
dev: false
|
||||
|
||||
/querystring@0.2.0:
|
||||
resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==}
|
||||
engines: {node: '>=0.4.x'}
|
||||
@@ -5717,10 +5774,6 @@ packages:
|
||||
resolve: 1.22.6
|
||||
dev: false
|
||||
|
||||
/regenerator-runtime@0.14.0:
|
||||
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
|
||||
dev: false
|
||||
|
||||
/regexp-tree@0.1.27:
|
||||
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
|
||||
hasBin: true
|
||||
@@ -5744,57 +5797,6 @@ packages:
|
||||
resolution: {integrity: sha512-x917M80K97K5IN1L8lUvFehsfhR8cYjGQ/yAMRI9E7JIKivtl5Emo5iD13DhMr+VojzMCiYk8V2byNPwT/oapg==}
|
||||
dev: false
|
||||
|
||||
/request-promise-core@1.1.4(request@2.88.2):
|
||||
resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
peerDependencies:
|
||||
request: ^2.34
|
||||
dependencies:
|
||||
lodash: 4.17.21
|
||||
request: 2.88.2
|
||||
dev: false
|
||||
|
||||
/request-promise@4.2.6(request@2.88.2):
|
||||
resolution: {integrity: sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
|
||||
peerDependencies:
|
||||
request: ^2.34
|
||||
dependencies:
|
||||
bluebird: 3.7.2
|
||||
request: 2.88.2
|
||||
request-promise-core: 1.1.4(request@2.88.2)
|
||||
stealthy-require: 1.1.1
|
||||
tough-cookie: 2.5.0
|
||||
dev: false
|
||||
|
||||
/request@2.88.2:
|
||||
resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==}
|
||||
engines: {node: '>= 6'}
|
||||
deprecated: request has been deprecated, see https://github.com/request/request/issues/3142
|
||||
dependencies:
|
||||
aws-sign2: 0.7.0
|
||||
aws4: 1.12.0
|
||||
caseless: 0.12.0
|
||||
combined-stream: 1.0.8
|
||||
extend: 3.0.2
|
||||
forever-agent: 0.6.1
|
||||
form-data: 2.3.3
|
||||
har-validator: 5.1.5
|
||||
http-signature: 1.2.0
|
||||
is-typedarray: 1.0.0
|
||||
isstream: 0.1.2
|
||||
json-stringify-safe: 5.0.1
|
||||
mime-types: 2.1.35
|
||||
oauth-sign: 0.9.0
|
||||
performance-now: 2.1.0
|
||||
qs: 6.5.3
|
||||
safe-buffer: 5.2.1
|
||||
tough-cookie: 2.5.0
|
||||
tunnel-agent: 0.6.0
|
||||
uuid: 3.4.0
|
||||
dev: false
|
||||
|
||||
/require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -5934,10 +5936,6 @@ packages:
|
||||
resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==}
|
||||
dev: false
|
||||
|
||||
/sax@1.3.0:
|
||||
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
|
||||
dev: false
|
||||
|
||||
/saxes@6.0.0:
|
||||
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
||||
engines: {node: '>=v12.22.7'}
|
||||
@@ -6168,36 +6166,11 @@ packages:
|
||||
engines: {node: '>= 10.x'}
|
||||
dev: false
|
||||
|
||||
/sprintf-js@1.0.3:
|
||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||
dev: false
|
||||
|
||||
/sshpk@1.17.0:
|
||||
resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
asn1: 0.2.6
|
||||
assert-plus: 1.0.0
|
||||
bcrypt-pbkdf: 1.0.2
|
||||
dashdash: 1.14.1
|
||||
ecc-jsbn: 0.1.2
|
||||
getpass: 0.1.7
|
||||
jsbn: 0.1.1
|
||||
safer-buffer: 2.1.2
|
||||
tweetnacl: 0.14.5
|
||||
dev: false
|
||||
|
||||
/statuses@2.0.1:
|
||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/stealthy-require@1.1.1:
|
||||
resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/streamsearch@1.1.0:
|
||||
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -6421,14 +6394,6 @@ packages:
|
||||
nopt: 1.0.10
|
||||
dev: true
|
||||
|
||||
/tough-cookie@2.5.0:
|
||||
resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
|
||||
engines: {node: '>=0.8'}
|
||||
dependencies:
|
||||
psl: 1.9.0
|
||||
punycode: 2.3.0
|
||||
dev: false
|
||||
|
||||
/tough-cookie@4.1.3:
|
||||
resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -6495,10 +6460,6 @@ packages:
|
||||
domino: 2.1.6
|
||||
dev: false
|
||||
|
||||
/tweetnacl@0.14.5:
|
||||
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
|
||||
dev: false
|
||||
|
||||
/twemoji-parser@14.0.0:
|
||||
resolution: {integrity: sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==}
|
||||
dev: false
|
||||
@@ -6714,12 +6675,6 @@ packages:
|
||||
engines: {node: '>= 0.4.0'}
|
||||
dev: false
|
||||
|
||||
/uuid@3.4.0:
|
||||
resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
|
||||
deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/uuid@8.0.0:
|
||||
resolution: {integrity: sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==}
|
||||
hasBin: true
|
||||
@@ -6887,19 +6842,19 @@ packages:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/xml-crypto@2.1.5:
|
||||
resolution: {integrity: sha512-xOSJmGFm+BTXmaPYk8pPV3duKo6hJuZ5niN4uMzoNcTlwYs0jAu/N3qY+ud9MhE4N7eMRuC1ayC7Yhmb7MmAWg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
/xml-crypto@3.2.0:
|
||||
resolution: {integrity: sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
dependencies:
|
||||
'@xmldom/xmldom': 0.7.13
|
||||
'@xmldom/xmldom': 0.8.10
|
||||
xpath: 0.0.32
|
||||
dev: false
|
||||
|
||||
/xml-encryption@2.0.0:
|
||||
resolution: {integrity: sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q==}
|
||||
/xml-encryption@3.0.2:
|
||||
resolution: {integrity: sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@xmldom/xmldom': 0.7.13
|
||||
'@xmldom/xmldom': 0.8.10
|
||||
escape-html: 1.0.3
|
||||
xpath: 0.0.32
|
||||
dev: false
|
||||
@@ -6909,14 +6864,6 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/xml2js@0.4.23:
|
||||
resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
dependencies:
|
||||
sax: 1.3.0
|
||||
xmlbuilder: 11.0.1
|
||||
dev: false
|
||||
|
||||
/xml2js@0.4.4:
|
||||
resolution: {integrity: sha512-9ERdxLOo4EazMDHAS/vsuZiTXIMur6ydcRfzGrFVJ4qM78zD3ohUgPJC7NYpGwd5rnS0ufSydMJClh6jyH+V0w==}
|
||||
dependencies:
|
||||
@@ -6946,6 +6893,11 @@ packages:
|
||||
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
||||
dev: false
|
||||
|
||||
/xpath@0.0.27:
|
||||
resolution: {integrity: sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==}
|
||||
engines: {node: '>=0.6.0'}
|
||||
dev: false
|
||||
|
||||
/xpath@0.0.32:
|
||||
resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==}
|
||||
engines: {node: '>=0.6.0'}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"@lezer/common": "1.1.0",
|
||||
"@mdi/font": "7.3.67",
|
||||
"@quasar/extras": "1.16.7",
|
||||
"@simplewebauthn/browser": "8.3.1",
|
||||
"@tiptap/core": "2.1.11",
|
||||
"@tiptap/extension-code-block": "2.1.11",
|
||||
"@tiptap/extension-code-block-lowlight": "2.1.11",
|
||||
|
||||
Generated
+13
@@ -17,6 +17,9 @@ dependencies:
|
||||
'@quasar/extras':
|
||||
specifier: 1.16.7
|
||||
version: 1.16.7
|
||||
'@simplewebauthn/browser':
|
||||
specifier: 8.3.1
|
||||
version: 8.3.1
|
||||
'@tiptap/core':
|
||||
specifier: 2.1.11
|
||||
version: 2.1.11(@tiptap/pm@2.1.11)
|
||||
@@ -709,6 +712,16 @@ packages:
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/@simplewebauthn/browser@8.3.1:
|
||||
resolution: {integrity: sha512-bMW7oOkxX4ydRAkkPtJ1do2k9yOoIGc/hZYebcuEOVdJoC6wwVpu97mYY7Mz8B9hLlcaR5WFgBsLl5tSJVzm8A==}
|
||||
dependencies:
|
||||
'@simplewebauthn/typescript-types': 8.0.0
|
||||
dev: false
|
||||
|
||||
/@simplewebauthn/typescript-types@8.0.0:
|
||||
resolution: {integrity: sha512-d7Izb2H+LZJteXMkS8DmpAarD6mZdpIOu/av/yH4/u/3Pd6DKFLyBM3j8BMmUvUqpzvJvHARNrRfQYto58mtTQ==}
|
||||
dev: false
|
||||
|
||||
/@socket.io/component-emitter@3.1.0:
|
||||
resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==}
|
||||
dev: false
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><linearGradient id="3pqdDc9GpRiC~~RXNJCBxa" x1="20.035" x2="4.818" y1="13.721" y2="29.585" gradientTransform="translate(0 14)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e5a505"/><stop offset=".01" stop-color="#e9a804"/><stop offset=".06" stop-color="#f4b102"/><stop offset=".129" stop-color="#fbb600"/><stop offset=".323" stop-color="#fdb700"/></linearGradient><path fill="url(#3pqdDc9GpRiC~~RXNJCBxa)" d="M12,41.5c0-1.381,1.119-2.5,2.5-2.5c0.156,0,0.307,0.019,0.454,0.046l1.186-1.186 C16.058,37.586,16,37.301,16,37c0-1.657,1.343-3,3-3c0.301,0,0.586,0.058,0.86,0.14L24,30l-6-6L4.586,37.414 C4.211,37.789,4,38.298,4,38.828v1.343c0,0.53,0.211,1.039,0.586,1.414l1.828,1.828C6.789,43.789,7.298,44,7.828,44h1.343 c0.53,0,1.039-0.211,1.414-0.586l1.46-1.46C12.019,41.807,12,41.656,12,41.5z"/><linearGradient id="3pqdDc9GpRiC~~RXNJCBxb" x1="21.64" x2="36.971" y1="-6.927" y2="15.362" gradientTransform="translate(0 14)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fede00"/><stop offset="1" stop-color="#ffd000"/></linearGradient><path fill="url(#3pqdDc9GpRiC~~RXNJCBxb)" d="M29.5,5C22.044,5,16,11.044,16,18.5S22.044,32,29.5,32S43,25.956,43,18.5S36.956,5,29.5,5z M33,19c-2.209,0-4-1.791-4-4s1.791-4,4-4s4,1.791,4,4S35.209,19,33,19z"/><path d="M39.86,27.16c-0.12,0.15-0.25,0.3-0.38,0.44c-2.47,2.7-6.03,4.4-9.98,4.4 h-0.11c-0.2,0-0.39-0.01-0.59-0.02c1.96-3,5.35-4.98,9.2-4.98C38.63,27,39.25,27.05,39.86,27.16z" opacity=".05"/><path d="M39.48,27.6c-2.47,2.7-6.03,4.4-9.98,4.4h-0.11 c1.9-2.72,5.05-4.5,8.61-4.5C38.5,27.5,39,27.54,39.48,27.6z" opacity=".07"/><linearGradient id="3pqdDc9GpRiC~~RXNJCBxc" x1="33.304" x2="42.696" y1="88.831" y2="71.169" gradientTransform="matrix(1 0 0 -1 0 118)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#21ad64"/><stop offset="1" stop-color="#088242"/></linearGradient><circle cx="38" cy="38" r="10" fill="url(#3pqdDc9GpRiC~~RXNJCBxc)"/><path fill="#fff" d="M38.5,43h-1c-0.276,0-0.5-0.224-0.5-0.5v-9c0-0.276,0.224-0.5,0.5-0.5h1c0.276,0,0.5,0.224,0.5,0.5v9 C39,42.776,38.776,43,38.5,43z"/><path fill="#fff" d="M33,38.5v-1c0-0.276,0.224-0.5,0.5-0.5h9c0.276,0,0.5,0.224,0.5,0.5v1c0,0.276-0.224,0.5-0.5,0.5h-9 C33.224,39,33,38.776,33,38.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><path fill="#35c1f1" d="M21,23c-0.553,0-1,0.447-1,1v3c0,0.553,0.447,1,1,1s1-0.447,1-1v-3C22,23.447,21.553,23,21,23z"/><path fill="#35c1f1" d="M21,30c-0.553,0-1,0.447-1,1v12c0,0.553,0.447,1,1,1s1-0.447,1-1V31C22,30.447,21.553,30,21,30z"/><path fill="#35c1f1" d="M20.501,19.024C17.903,19.278,16,21.613,16,24.223V42c0,0.553,0.447,1,1,1s1-0.447,1-1V24.119 c0-1.451,0.977-2.784,2.402-3.061C22.317,20.686,24,22.15,24,24v18c0,0.553,0.447,1,1,1s1-0.447,1-1V24 C26,21.078,23.481,18.734,20.501,19.024z"/><path fill="#35c1f1" d="M21.252,15.003c-1.336-0.037-2.636,0.218-3.86,0.755c-0.506,0.221-0.737,0.811-0.515,1.317 c0.222,0.505,0.81,0.737,1.317,0.515c1.1-0.483,2.278-0.671,3.484-0.558C25.313,17.374,28,20.603,28,24.254V38c0,0.553,0.447,1,1,1 s1-0.447,1-1V24.345C30,19.414,26.182,15.139,21.252,15.003z"/><path fill="#35c1f1" d="M13.848,18.552C12.639,20.137,12,22.021,12,24v17c0,0.553,0.447,1,1,1s1-0.447,1-1V24 c0-1.538,0.497-3.002,1.437-4.235c0.335-0.439,0.251-1.066-0.188-1.401C14.81,18.027,14.182,18.114,13.848,18.552z"/><path fill="#35c1f1" d="M20.345,11.016C13.362,11.361,8,17.386,8,24.377V28c0,0.553,0.447,1,1,1s1-0.447,1-1v-3.677 c0-5.724,4.24-10.736,9.939-11.273C26.479,12.434,32,17.585,32,24v14.678c0,0.553,0.447,1,1,1s1-0.448,1-1V24 C34,16.615,27.809,10.648,20.345,11.016z"/><path fill="#35c1f1" d="M9,31c-0.553,0-1,0.447-1,1v5v1.678V39c0,0.552,0.448,1,1,1s1-0.448,1-1v-0.322V37v-5 C10,31.447,9.553,31,9,31z"/><path fill="#35c1f1" d="M30.958,11.458c-0.37,0.41-0.338,1.043,0.072,1.412C34.188,15.719,36,19.775,36,24v10 c0,0.553,0.447,1,1,1s1-0.447,1-1V24c0-4.79-2.052-9.388-5.63-12.614C31.96,11.016,31.328,11.048,30.958,11.458z"/><path fill="#35c1f1" d="M21,9c2.422,0,4.745,0.569,6.904,1.693c0.49,0.255,1.094,0.063,1.349-0.425 c0.255-0.491,0.064-1.094-0.425-1.349C26.38,7.646,23.747,7,21,7c-6.048,0-11.689,3.267-14.724,8.525 C6,16.004,6.164,16.615,6.643,16.891c0.157,0.091,0.329,0.134,0.499,0.134c0.345,0,0.681-0.179,0.867-0.5 C10.687,11.884,15.665,9,21,9z"/><path fill="#35c1f1" d="M5.841,18.824c-0.531-0.149-1.082,0.17-1.228,0.702C4.206,21.023,4,22.528,4,24v10 c0,0.553,0.447,1,1,1s1-0.447,1-1V24c0-1.294,0.183-2.623,0.543-3.948C6.688,19.518,6.373,18.969,5.841,18.824z"/><path fill="#35c1f1" d="M41.808,21.301c-0.07-0.548-0.565-0.927-1.119-0.865c-0.548,0.07-0.935,0.571-0.865,1.119 C39.944,22.488,40,23.265,40,24v3v2.45c0,0.552,0.448,1,1,1l0,0c0.552,0,1-0.448,1-1V27v-3C42,23.178,41.939,22.319,41.808,21.301z"/><path fill="#35c1f1" d="M5.695,11.122c-0.439-0.334-1.066-0.249-1.401,0.19C1.484,15.004,0,19.392,0,24v6 c0,0.553,0.447,1,1,1s1-0.447,1-1v-6c0-4.168,1.344-8.136,3.885-11.477C6.219,12.084,6.134,11.457,5.695,11.122z"/><path fill="#35c1f1" d="M40.22,18.432c0.521-0.179,0.799-0.749,0.619-1.271C37.919,8.691,29.946,3,21,3 C15.915,3,10.999,4.859,7.155,8.236C6.74,8.601,6.699,9.232,7.065,9.647c0.364,0.414,0.996,0.455,1.411,0.091 C11.953,6.683,16.401,5,21,5c8.093,0,15.306,5.149,17.949,12.813c0.142,0.414,0.53,0.674,0.945,0.674 C40.002,18.487,40.111,18.47,40.22,18.432z"/><path d="M28,33.41c0.5-1.09,1.18-2.09,2-2.96V38c0,0.55-0.45,1-1,1s-1-0.45-1-1 V33.41z" opacity=".05"/><path d="M32,28.78c0.62-0.41,1.29-0.75,2-1.03v8.93c0,0.55-0.45,1-1,1s-1-0.45-1-1 V28.78z" opacity=".05"/><path d="M38,27v5c0,0.55-0.45,1-1,1s-1-0.45-1-1v-4.82C36.65,27.06,37.32,27,38,27 z" opacity=".05"/><path d="M28,34.79c0.43-1.33,1.12-2.54,2-3.58V38c0,0.55-0.45,1-1,1s-1-0.45-1-1 V34.79z" opacity=".07"/><path d="M32,29.39c0.62-0.44,1.29-0.8,2-1.09v8.38c0,0.55-0.45,1-1,1s-1-0.45-1-1 V29.39z" opacity=".07"/><path d="M38,27.5V32c0,0.55-0.45,1-1,1s-1-0.45-1-1v-4.31 C36.65,27.57,37.32,27.5,38,27.5z" opacity=".07"/><path d="M42,27.75v1.7c0,0.55-0.45,1-1,1s-1-0.45-1-1v-2.27 C40.69,27.31,41.36,27.5,42,27.75z" opacity=".05"/><path d="M42,28.3v1.15c0,0.55-0.45,1-1,1s-1-0.45-1-1v-1.76 C40.69,27.83,41.37,28.03,42,28.3z" opacity=".07"/><linearGradient id="hns_QSPvAuABanH5z5S5qa" x1="33.304" x2="42.696" y1="90.831" y2="73.169" gradientTransform="matrix(1 0 0 -1 0 120)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#21ad64"/><stop offset="1" stop-color="#088242"/></linearGradient><circle cx="38" cy="38" r="10" fill="url(#hns_QSPvAuABanH5z5S5qa)"/><path fill="#fff" d="M38.5,43h-1c-0.276,0-0.5-0.224-0.5-0.5v-9c0-0.276,0.224-0.5,0.5-0.5h1c0.276,0,0.5,0.224,0.5,0.5v9 C39,42.776,38.776,43,38.5,43z"/><path fill="#fff" d="M33,38.5v-1c0-0.276,0.224-0.5,0.5-0.5h9c0.276,0,0.5,0.224,0.5,0.5v1c0,0.276-0.224,0.5-0.5,0.5h-9 C33.224,39,33,38.776,33,38.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,83 @@
|
||||
<template lang="pug">
|
||||
q-dialog(ref='dialogRef', @hide='onDialogHide', persistent)
|
||||
q-card(style='min-width: 650px;')
|
||||
q-card-section.card-header
|
||||
q-icon(name='img:/_assets/icons/fluent-add-key.svg', left, size='sm')
|
||||
span {{t(`profile.passkeysAdd`)}}
|
||||
.q-py-sm
|
||||
.text-body2.q-px-md.q-py-sm {{t(`profile.passkeysNameHint`)}}
|
||||
q-item
|
||||
blueprint-icon(icon='key')
|
||||
q-item-section
|
||||
q-input(
|
||||
outlined
|
||||
v-model='state.name'
|
||||
dense
|
||||
hide-bottom-space
|
||||
:label='t(`profile.passkeysName`)'
|
||||
:aria-label='t(`profile.passkeysName`)'
|
||||
autofocus
|
||||
@keyup.enter='save'
|
||||
)
|
||||
q-card-actions.card-actions
|
||||
q-space
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
:label='t(`common.actions.cancel`)'
|
||||
color='grey'
|
||||
padding='xs md'
|
||||
@click='onDialogCancel'
|
||||
)
|
||||
q-btn(
|
||||
unelevated
|
||||
:label='t(`common.actions.save`)'
|
||||
color='primary'
|
||||
padding='xs md'
|
||||
@click='save'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useDialogPluginComponent, useQuasar } from 'quasar'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
// EMITS
|
||||
|
||||
defineEmits([
|
||||
...useDialogPluginComponent.emits
|
||||
])
|
||||
|
||||
// QUASAR
|
||||
|
||||
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
|
||||
const $q = useQuasar()
|
||||
|
||||
// I18N
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// DATA
|
||||
|
||||
const state = reactive({
|
||||
name: ''
|
||||
})
|
||||
|
||||
// METHODS
|
||||
|
||||
async function save () {
|
||||
try {
|
||||
if (!state.name || state.name.trim().length < 1 || state.name.length > 255) {
|
||||
throw new Error(t('profile.passkeysInvalidName'))
|
||||
}
|
||||
onDialogOK({
|
||||
name: state.name
|
||||
})
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: err.message
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,97 +1,57 @@
|
||||
<template lang="pug">
|
||||
q-dialog(ref='dialogRef', @hide='onDialogHide')
|
||||
q-card(style='min-width: 650px;')
|
||||
q-dialog(ref='dialogRef', @hide='onDialogHide', persistent)
|
||||
q-card.setup2fadialog(style='min-width: 450px;')
|
||||
q-card-section.card-header
|
||||
q-icon(name='img:/_assets/icons/fluent-password-reset.svg', left, size='sm')
|
||||
span {{t(`admin.users.changePassword`)}}
|
||||
q-form.q-py-sm(ref='changeUserPwdForm', @submit='save')
|
||||
q-item
|
||||
blueprint-icon(icon='lock')
|
||||
q-item-section
|
||||
q-input(
|
||||
outlined
|
||||
v-model='state.currentPassword'
|
||||
dense
|
||||
:rules='currentPasswordValidation'
|
||||
hide-bottom-space
|
||||
:label='t(`auth.changePwd.currentPassword`)'
|
||||
:aria-label='t(`auth.changePwd.currentPassword`)'
|
||||
lazy-rules='ondemand'
|
||||
autofocus
|
||||
)
|
||||
q-item
|
||||
blueprint-icon(icon='password')
|
||||
q-item-section
|
||||
q-input(
|
||||
outlined
|
||||
v-model='state.newPassword'
|
||||
dense
|
||||
:rules='newPasswordValidation'
|
||||
hide-bottom-space
|
||||
:label='t(`auth.changePwd.newPassword`)'
|
||||
:aria-label='t(`auth.changePwd.newPassword`)'
|
||||
lazy-rules='ondemand'
|
||||
autofocus
|
||||
)
|
||||
template(#append)
|
||||
.flex.items-center
|
||||
q-badge(
|
||||
:color='passwordStrength.color'
|
||||
:label='passwordStrength.label'
|
||||
)
|
||||
q-separator.q-mx-sm(vertical)
|
||||
q-btn(
|
||||
flat
|
||||
dense
|
||||
padding='none xs'
|
||||
color='brown'
|
||||
@click='randomizePassword'
|
||||
)
|
||||
q-icon(name='las la-dice-d6')
|
||||
.q-pl-xs.text-caption: strong Generate
|
||||
q-item
|
||||
blueprint-icon(icon='good-pincode')
|
||||
q-item-section
|
||||
q-input(
|
||||
outlined
|
||||
v-model='state.verifyPassword'
|
||||
dense
|
||||
:rules='verifyPasswordValidation'
|
||||
hide-bottom-space
|
||||
:label='t(`auth.changePwd.newPasswordVerify`)'
|
||||
:aria-label='t(`auth.changePwd.newPasswordVerify`)'
|
||||
lazy-rules='ondemand'
|
||||
autofocus
|
||||
)
|
||||
q-card-actions.card-actions
|
||||
q-space
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
:label='t(`common.actions.cancel`)'
|
||||
color='grey'
|
||||
padding='xs md'
|
||||
@click='onDialogCancel'
|
||||
)
|
||||
q-btn(
|
||||
unelevated
|
||||
:label='t(`common.actions.update`)'
|
||||
color='primary'
|
||||
padding='xs md'
|
||||
@click='save'
|
||||
:loading='state.isLoading'
|
||||
)
|
||||
q-icon(name='img:/_assets/icons/fluent-fingerprint.svg', left, size='sm')
|
||||
span {{t(`profile.authSetTfa`)}}
|
||||
template(v-if='!state.isInit')
|
||||
q-linear-progress(query, color='positive')
|
||||
q-card-section.text-center.text-grey {{t(`profile.authSetTfaLoading`)}}
|
||||
template(v-else)
|
||||
q-card-section.text-center
|
||||
p {{t('auth.tfaSetupInstrFirst')}}
|
||||
div(style='justify-content: center; display: flex;')
|
||||
div(v-html='state.tfaQRImage', style='width: 200px;')
|
||||
p.q-mt-sm {{t('auth.tfaSetupInstrSecond')}}
|
||||
.flex.justify-center
|
||||
v-otp-input(
|
||||
v-model:value='state.securityCode'
|
||||
:num-inputs='6'
|
||||
:should-auto-focus='true'
|
||||
input-classes='otp-input'
|
||||
input-type='number'
|
||||
separator=''
|
||||
)
|
||||
q-inner-loading(:showing='state.isLoading')
|
||||
q-card-actions.card-actions
|
||||
q-space
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
:label='t(`common.actions.cancel`)'
|
||||
color='grey'
|
||||
padding='xs md'
|
||||
@click='onDialogCancel'
|
||||
)
|
||||
q-btn(
|
||||
unelevated
|
||||
:label='t(`auth.tfa.verifyToken`)'
|
||||
color='primary'
|
||||
padding='xs md'
|
||||
@click='save'
|
||||
:loading='state.isLoading'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import gql from 'graphql-tag'
|
||||
import zxcvbn from 'zxcvbn'
|
||||
import { sampleSize } from 'lodash-es'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useDialogPluginComponent, useQuasar } from 'quasar'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { onMounted, reactive } from 'vue'
|
||||
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
|
||||
import VOtpInput from 'vue3-otp-input'
|
||||
|
||||
// PROPS
|
||||
|
||||
const props = defineProps({
|
||||
@@ -123,96 +83,78 @@ const { t } = useI18n()
|
||||
// DATA
|
||||
|
||||
const state = reactive({
|
||||
currentPassword: '',
|
||||
newPassword: '',
|
||||
verifyPassword: '',
|
||||
isLoading: false
|
||||
isInit: false,
|
||||
isLoading: false,
|
||||
securityCode: '',
|
||||
tfaQRImage: '',
|
||||
continuationToken: ''
|
||||
})
|
||||
|
||||
// REFS
|
||||
|
||||
const changeUserPwdForm = ref(null)
|
||||
|
||||
// COMPUTED
|
||||
|
||||
const passwordStrength = computed(() => {
|
||||
if (state.newPassword.length < 8) {
|
||||
return {
|
||||
color: 'negative',
|
||||
label: t('admin.users.pwdStrengthWeak')
|
||||
}
|
||||
} else {
|
||||
switch (zxcvbn(state.newPassword).score) {
|
||||
case 1:
|
||||
return {
|
||||
color: 'deep-orange-7',
|
||||
label: t('admin.users.pwdStrengthPoor')
|
||||
}
|
||||
case 2:
|
||||
return {
|
||||
color: 'purple-7',
|
||||
label: t('admin.users.pwdStrengthMedium')
|
||||
}
|
||||
case 3:
|
||||
return {
|
||||
color: 'blue-7',
|
||||
label: t('admin.users.pwdStrengthGood')
|
||||
}
|
||||
case 4:
|
||||
return {
|
||||
color: 'green-7',
|
||||
label: t('admin.users.pwdStrengthStrong')
|
||||
}
|
||||
default:
|
||||
return {
|
||||
color: 'negative',
|
||||
label: t('admin.users.pwdStrengthWeak')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// VALIDATION RULES
|
||||
|
||||
const currentPasswordValidation = [
|
||||
val => val.length > 0 || t('auth.errors.missingPassword')
|
||||
]
|
||||
const newPasswordValidation = [
|
||||
val => val.length > 0 || t('auth.errors.missingPassword'),
|
||||
val => val.length >= 8 || t('auth.errors.passwordTooShort')
|
||||
]
|
||||
const verifyPasswordValidation = [
|
||||
val => val.length > 0 || t('auth.errors.missingVerifyPassword'),
|
||||
val => val === state.newPassword || t('auth.errors.passwordsNotMatch')
|
||||
]
|
||||
|
||||
// METHODS
|
||||
|
||||
function randomizePassword () {
|
||||
const pwdChars = 'abcdefghkmnpqrstuvwxyzABCDEFHJKLMNPQRSTUVWXYZ23456789_*=?#!()+'
|
||||
state.newPassword = sampleSize(pwdChars, 16).join('')
|
||||
async function load () {
|
||||
state.isInit = false
|
||||
try {
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation setupTfa (
|
||||
$strategyId: UUID!
|
||||
$siteId: UUID!
|
||||
) {
|
||||
setupTFA (
|
||||
strategyId: $strategyId
|
||||
siteId: $siteId
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
message
|
||||
}
|
||||
continuationToken
|
||||
tfaQRImage
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
strategyId: props.strategyId,
|
||||
siteId: siteStore.id
|
||||
}
|
||||
})
|
||||
if (resp?.data?.setupTFA?.operation?.succeeded) {
|
||||
state.continuationToken = resp.data.setupTFA.continuationToken
|
||||
state.tfaQRImage = resp.data.setupTFA.tfaQRImage
|
||||
state.isInit = true
|
||||
} else {
|
||||
throw new Error(resp?.data?.setupTFA?.operation?.message || 'An unexpected error occured.')
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: err.message
|
||||
})
|
||||
onDialogCancel()
|
||||
}
|
||||
}
|
||||
|
||||
async function save () {
|
||||
state.isLoading = true
|
||||
try {
|
||||
const isFormValid = await changeUserPwdForm.value.validate(true)
|
||||
if (!isFormValid) {
|
||||
throw new Error(t('auth.errors.fields'))
|
||||
if (!/^[0-9]{6}$/.test(state.securityCode)) {
|
||||
throw new Error(t('auth.errors.tfaMissing'))
|
||||
}
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation changePwd (
|
||||
$currentPassword: String
|
||||
$newPassword: String!
|
||||
mutation(
|
||||
$continuationToken: String!
|
||||
$securityCode: String!
|
||||
$strategyId: UUID!
|
||||
$siteId: UUID!
|
||||
) {
|
||||
changePassword (
|
||||
currentPassword: $currentPassword
|
||||
newPassword: $newPassword
|
||||
loginTFA(
|
||||
continuationToken: $continuationToken
|
||||
securityCode: $securityCode
|
||||
strategyId: $strategyId
|
||||
siteId: $siteId
|
||||
setup: true
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
@@ -222,20 +164,23 @@ async function save () {
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
currentPassword: state.currentPassword,
|
||||
newPassword: state.newPassword,
|
||||
continuationToken: state.continuationToken,
|
||||
securityCode: state.securityCode,
|
||||
strategyId: props.strategyId,
|
||||
siteId: siteStore.id
|
||||
}
|
||||
})
|
||||
if (resp?.data?.changePassword?.operation?.succeeded) {
|
||||
if (resp.data?.loginTFA?.operation?.succeeded) {
|
||||
state.continuationToken = ''
|
||||
state.securityCode = ''
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: t('auth.changePwd.success')
|
||||
message: t('auth.tfaSetupSuccess')
|
||||
})
|
||||
state.isLoading = false
|
||||
onDialogOK()
|
||||
} else {
|
||||
throw new Error(resp?.data?.changePassword?.operation?.message || 'An unexpected error occured.')
|
||||
throw new Error(resp.data?.loginTFA?.operation?.message || t('auth.errors.loginError'))
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
@@ -245,4 +190,46 @@ async function save () {
|
||||
}
|
||||
state.isLoading = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.setup2fadialog {
|
||||
.otp-input {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding: 5px;
|
||||
margin: 0 5px 7px;
|
||||
font-size: 20px;
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
|
||||
@at-root .body--light & {
|
||||
border: 2px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
@at-root .body--dark & {
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline-color: $primary;
|
||||
}
|
||||
|
||||
/* Background colour of an input field with value */
|
||||
&.is-complete {
|
||||
border-color: $positive;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
&::-webkit-inner-spin-button,
|
||||
&::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Parse an error message for an error code and translate
|
||||
*
|
||||
* @param {String} val Value to parse
|
||||
* @param {Function} t vue-i18n translation method
|
||||
*/
|
||||
export function localizeError (val, t) {
|
||||
if (val?.startsWith('ERR_')) {
|
||||
return t(`error.${val}`)
|
||||
} else {
|
||||
return val
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,7 @@ q-page.admin-locale
|
||||
icon='las la-trash'
|
||||
color='negative'
|
||||
@click='deleteSite(site)'
|
||||
:aria-label='t(`common.actions.delete`)'
|
||||
)
|
||||
</template>
|
||||
|
||||
|
||||
@@ -47,6 +47,46 @@ q-page.q-py-md(:style-fn='pageStyle')
|
||||
@click='changePassword(auth.authId)'
|
||||
)
|
||||
|
||||
.text-header.q-mt-md {{t('profile.passkeys')}}
|
||||
.q-pa-md
|
||||
.text-body2 {{ t('profile.passkeysIntro') }}
|
||||
q-list.q-mt-lg(
|
||||
v-if="state.passkeys?.length > 0"
|
||||
bordered
|
||||
separator
|
||||
)
|
||||
q-item(
|
||||
v-for='pkey of state.passkeys'
|
||||
:key='pkey.id'
|
||||
)
|
||||
q-item-section(avatar)
|
||||
q-avatar(
|
||||
color='secondary'
|
||||
text-color='white'
|
||||
rounded
|
||||
)
|
||||
q-icon(name='las la-key')
|
||||
q-item-section
|
||||
strong {{pkey.name}}
|
||||
.text-caption {{ pkey.siteHostname }}
|
||||
.text-caption.text-grey-7 {{ humanizeDate(pkey.createdAt) }}
|
||||
q-item-section(side)
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
icon='las la-trash'
|
||||
:aria-label='t(`common.actions.delete`)'
|
||||
color='negative'
|
||||
@click='deactivatePasskey(pkey)'
|
||||
)
|
||||
.q-mt-md
|
||||
q-btn(
|
||||
icon='las la-plus'
|
||||
unelevated
|
||||
:label='t(`profile.passkeysAdd`)'
|
||||
color='primary'
|
||||
@click='setupPasskey'
|
||||
)
|
||||
|
||||
q-inner-loading(:showing='state.loading > 0')
|
||||
</template>
|
||||
|
||||
@@ -55,11 +95,16 @@ import gql from 'graphql-tag'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { onMounted, reactive } from 'vue'
|
||||
import { browserSupportsWebAuthn, startRegistration } from '@simplewebauthn/browser'
|
||||
import { localizeError } from 'src/helpers/localization'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
import { useUserStore } from 'src/stores/user'
|
||||
|
||||
import ChangePwdDialog from 'src/components/ChangePwdDialog.vue'
|
||||
import SetupTfaDialog from 'src/components/SetupTfaDialog.vue'
|
||||
import PasskeyCreateDialog from 'src/components/PasskeyCreateDialog.vue'
|
||||
|
||||
// QUASAR
|
||||
|
||||
@@ -67,6 +112,7 @@ const $q = useQuasar()
|
||||
|
||||
// STORES
|
||||
|
||||
const siteStore = useSiteStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// I18N
|
||||
@@ -83,6 +129,7 @@ useMeta({
|
||||
|
||||
const state = reactive({
|
||||
authMethods: [],
|
||||
passkeys: [],
|
||||
loading: 0
|
||||
})
|
||||
|
||||
@@ -94,6 +141,10 @@ function pageStyle (offset, height) {
|
||||
}
|
||||
}
|
||||
|
||||
function humanizeDate (val) {
|
||||
return DateTime.fromISO(val).toLocaleString(DateTime.DATETIME_MED)
|
||||
}
|
||||
|
||||
async function fetchAuthMethods () {
|
||||
state.loading++
|
||||
try {
|
||||
@@ -113,6 +164,12 @@ async function fetchAuthMethods () {
|
||||
strategyIcon
|
||||
config
|
||||
}
|
||||
passkeys {
|
||||
id
|
||||
name
|
||||
createdAt
|
||||
siteHostname
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -122,6 +179,7 @@ async function fetchAuthMethods () {
|
||||
fetchPolicy: 'network-only'
|
||||
})
|
||||
state.authMethods = respRaw.data?.userById?.auth ?? []
|
||||
state.passkeys = respRaw.data?.userById?.passkeys ?? []
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
@@ -189,12 +247,166 @@ function disableTfa (strategyId) {
|
||||
}
|
||||
|
||||
function setupTfa (strategyId) {
|
||||
// $q.dialog({
|
||||
// component: SetupTfaDialog,
|
||||
// componentProps: {
|
||||
// strategyId
|
||||
// }
|
||||
// })
|
||||
$q.dialog({
|
||||
component: SetupTfaDialog,
|
||||
componentProps: {
|
||||
strategyId
|
||||
}
|
||||
}).onOk(() => {
|
||||
fetchAuthMethods()
|
||||
})
|
||||
}
|
||||
|
||||
async function setupPasskey () {
|
||||
try {
|
||||
if (!browserSupportsWebAuthn()) {
|
||||
throw new Error(t('profile.passkeysUnsupported'))
|
||||
}
|
||||
$q.loading.show()
|
||||
|
||||
// -> Generation registration options
|
||||
|
||||
const genResp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation setupPasskey (
|
||||
$siteId: UUID!
|
||||
) {
|
||||
setupPasskey(
|
||||
siteId: $siteId
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
message
|
||||
}
|
||||
registrationOptions
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
siteId: siteStore.id
|
||||
}
|
||||
})
|
||||
if (genResp?.data?.setupPasskey?.operation?.succeeded) {
|
||||
state.registrationOptions = genResp.data.setupPasskey.registrationOptions
|
||||
} else {
|
||||
throw new Error(localizeError(genResp?.data?.setupPasskey?.operation?.message, t))
|
||||
}
|
||||
|
||||
// -> Start registration on the authenticator
|
||||
|
||||
let attResp
|
||||
try {
|
||||
attResp = await startRegistration(state.registrationOptions)
|
||||
} catch (err) {
|
||||
if (err.name === 'InvalidStateError') {
|
||||
throw new Error(t('error.ERR_PK_ALREADY_REGISTERED'))
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// -> Prompt for passkey name
|
||||
|
||||
$q.loading.hide()
|
||||
const passkeyName = await new Promise((resolve, reject) => {
|
||||
$q.dialog({
|
||||
component: PasskeyCreateDialog
|
||||
}).onOk(({ name }) => {
|
||||
resolve(name)
|
||||
}).onCancel(() => {
|
||||
reject(new Error(t('error.ERR_PK_USER_CANCELLED')))
|
||||
})
|
||||
})
|
||||
$q.loading.show()
|
||||
|
||||
// -> Verify the authenticator response
|
||||
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation finalizePasskey (
|
||||
$registrationResponse: JSON!
|
||||
$name: String!
|
||||
) {
|
||||
finalizePasskey(
|
||||
registrationResponse: $registrationResponse
|
||||
name: $name
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
registrationResponse: attResp,
|
||||
name: passkeyName
|
||||
}
|
||||
})
|
||||
if (resp?.data?.finalizePasskey?.operation?.succeeded) {
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: t('profile.passkeysSetupSuccess')
|
||||
})
|
||||
} else {
|
||||
throw new Error(resp?.data?.finalizePasskey?.operation?.message)
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: t('profile.passkeysSetupFailed'),
|
||||
caption: err.message ?? 'An unexpected error occured.'
|
||||
})
|
||||
}
|
||||
await fetchAuthMethods()
|
||||
$q.loading.hide()
|
||||
}
|
||||
|
||||
async function deactivatePasskey (pkey) {
|
||||
$q.dialog({
|
||||
title: t('common.actions.confirm'),
|
||||
message: t('profile.passkeysDeactivateConfirm'),
|
||||
cancel: true
|
||||
}).onOk(async () => {
|
||||
$q.loading.show()
|
||||
try {
|
||||
const resp = await APOLLO_CLIENT.mutate({
|
||||
mutation: gql`
|
||||
mutation deactivatePasskey (
|
||||
$id: UUID!
|
||||
) {
|
||||
deactivatePasskey(
|
||||
id: $id
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
id: pkey.id
|
||||
}
|
||||
})
|
||||
if (resp?.data?.deactivatePasskey?.operation?.succeeded) {
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: t('profile.passkeysDeactivateSuccess')
|
||||
})
|
||||
} else {
|
||||
throw new Error(resp?.data?.deactivatePasskey?.operation?.message)
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: t('profile.passkeysDeactivateFailed'),
|
||||
caption: err.message ?? 'An unexpected error occured.'
|
||||
})
|
||||
}
|
||||
await fetchAuthMethods()
|
||||
$q.loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
// MOUNTED
|
||||
|
||||
Reference in New Issue
Block a user