From 939d834841ce62f513f90b4eec60c150791b7932 Mon Sep 17 00:00:00 2001 From: Appaji <52322531+CITIZENDOT@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:59:27 +0530 Subject: [PATCH] Fix identity-provider type issues & patch `@feathersjs/knex` (#10971) * Add `guest` & `admin` identity provider types * Add `didWallet` to identity-provider type enum Fix type errors * Remove `didWallet` from identityProvider types Comment out wallet related functions * remove unused type * Patch @feathersjs/knex to fix count * remove `admin` provider type --- .../components/UserMenu/menus/ProfileMenu.tsx | 91 ++++++++------- .../src/user/services/AuthService.ts | 108 +++++++++--------- packages/common/src/interfaces/AuthUser.ts | 2 +- .../src/schemas/social/invite.schema.ts | 2 + .../src/schemas/user/generate-token.schema.ts | 7 +- .../schemas/user/identity-provider.schema.ts | 7 +- .../identity-provider.test.ts | 1 - patches/@feathersjs+knex+5.0.5.patch | 21 ++++ 8 files changed, 133 insertions(+), 106 deletions(-) create mode 100644 patches/@feathersjs+knex+5.0.5.patch diff --git a/packages/client-core/src/user/components/UserMenu/menus/ProfileMenu.tsx b/packages/client-core/src/user/components/UserMenu/menus/ProfileMenu.tsx index 4c07cec7ce..b0f78dad6c 100755 --- a/packages/client-core/src/user/components/UserMenu/menus/ProfileMenu.tsx +++ b/packages/client-core/src/user/components/UserMenu/menus/ProfileMenu.tsx @@ -30,7 +30,6 @@ import { useTranslation } from 'react-i18next' import { Link, useLocation } from 'react-router-dom' import Avatar from '@etherealengine/client-core/src/common/components/Avatar' -import Button from '@etherealengine/client-core/src/common/components/Button' import commonStyles from '@etherealengine/client-core/src/common/components/common.module.scss' import ConfirmDialog from '@etherealengine/client-core/src/common/components/ConfirmDialog' import { AppleIcon } from '@etherealengine/client-core/src/common/components/Icons/AppleIcon' @@ -322,51 +321,51 @@ const ProfileMenu = ({ hideLogin, onClose, isPopover }: Props): JSX.Element => { // console.log('VC Request query result:', result) } - async function handleWalletLoginClick() { - const domain = window.location.origin - const challenge = '99612b24-63d9-11ea-b99f-4f66f3e4f81a' // TODO: generate - - console.log('Sending DIDAuth query...') - - const didAuthQuery: any = { - web: { - VerifiablePresentation: { - query: [ - { - type: 'DIDAuth' // request the controller's DID - }, - { - type: 'QueryByExample', - credentialQuery: [ - { - example: { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/xr/v1'], - // contains username and avatar icon - type: 'LoginDisplayCredential' - } - }, - { - example: { - '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/xr/v1'], - // various Ethereal Engine user preferences - type: 'UserPreferencesCredential' - } - } - ] - } - ], - challenge, - domain // e.g.: requestingparty.example.com - } - } - } + // async function handleWalletLoginClick() { + // const domain = window.location.origin + // const challenge = '99612b24-63d9-11ea-b99f-4f66f3e4f81a' // TODO: generate + + // console.log('Sending DIDAuth query...') + + // const didAuthQuery: any = { + // web: { + // VerifiablePresentation: { + // query: [ + // { + // type: 'DIDAuth' // request the controller's DID + // }, + // { + // type: 'QueryByExample', + // credentialQuery: [ + // { + // example: { + // '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/xr/v1'], + // // contains username and avatar icon + // type: 'LoginDisplayCredential' + // } + // }, + // { + // example: { + // '@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/xr/v1'], + // // various Ethereal Engine user preferences + // type: 'UserPreferencesCredential' + // } + // } + // ] + // } + // ], + // challenge, + // domain // e.g.: requestingparty.example.com + // } + // } + // } - // Use Credential Handler API to authenticate and receive basic login display credentials - const vprResult: any = await navigator.credentials.get(didAuthQuery) - console.log(vprResult) + // // Use Credential Handler API to authenticate and receive basic login display credentials + // const vprResult: any = await navigator.credentials.get(didAuthQuery) + // console.log(vprResult) - AuthService.loginUserByXRWallet(vprResult) - } + // AuthService.loginUserByXRWallet(vprResult) + // } const refreshApiKey = () => { AuthService.updateApiKey() @@ -752,7 +751,7 @@ const ProfileMenu = ({ hideLogin, onClose, isPopover }: Props): JSX.Element => { )} - {isGuest && enableWalletLogin && ( + {/* {isGuest && enableWalletLogin && ( <> {t('user:usermenu.profile.or')} @@ -776,7 +775,7 @@ const ProfileMenu = ({ hideLogin, onClose, isPopover }: Props): JSX.Element => { )} - )} + )} */} {enableSocial && ( <> diff --git a/packages/client-core/src/user/services/AuthService.ts b/packages/client-core/src/user/services/AuthService.ts index 1f20161471..0ea9010f87 100755 --- a/packages/client-core/src/user/services/AuthService.ts +++ b/packages/client-core/src/user/services/AuthService.ts @@ -317,41 +317,41 @@ export const AuthService = { * * @param vprResult {object} - VPR Query result from a user's wallet. */ - async loginUserByXRWallet(vprResult: any) { - const authState = getMutableState(AuthState) - try { - authState.merge({ isProcessing: true, error: '' }) - - const credentials: any = parseUserWalletCredentials(vprResult) - console.log(credentials) - - const walletUser = resolveWalletUser(credentials) - const authUser = { - accessToken: '', - authentication: { strategy: 'did-auth' }, - identityProvider: { - id: '', - token: '', - type: 'didWallet', - userId: walletUser.id, - createdAt: '', - updatedAt: '' - } - } - - // TODO: This is temp until we move completely to XR wallet #6453 - const oldId = authState.user.id.value - walletUser.id = oldId - - // loadXRAvatarForUpdatedUser(walletUser) - authState.merge({ isLoggedIn: true, user: walletUser, authUser }) - } catch (err) { - authState.merge({ error: i18n.t('common:error.login-error') }) - NotificationService.dispatchNotify(err.message, { variant: 'error' }) - } finally { - authState.merge({ isProcessing: false, error: '' }) - } - }, + // async loginUserByXRWallet(vprResult: any) { + // const authState = getMutableState(AuthState) + // try { + // authState.merge({ isProcessing: true, error: '' }) + + // const credentials: any = parseUserWalletCredentials(vprResult) + // console.log(credentials) + + // const walletUser = resolveWalletUser(credentials) + // const authUser = { + // accessToken: '', + // authentication: { strategy: 'did-auth' }, + // identityProvider: { + // id: '', + // token: '', + // type: 'didWallet', + // userId: walletUser.id, + // createdAt: '', + // updatedAt: '' + // } + // } + + // // TODO: This is temp until we move completely to XR wallet #6453 + // const oldId = authState.user.id.value + // walletUser.id = oldId + + // // loadXRAvatarForUpdatedUser(walletUser) + // authState.merge({ isLoggedIn: true, user: walletUser, authUser }) + // } catch (err) { + // authState.merge({ error: i18n.t('common:error.login-error') }) + // NotificationService.dispatchNotify(err.message, { variant: 'error' }) + // } finally { + // authState.merge({ isProcessing: false, error: '' }) + // } + // }, /** * Logs in the current user based on an OAuth response. @@ -725,25 +725,25 @@ export const AuthService = { /** * @param vprResult {any} See `loginUserByXRWallet()`'s docstring. */ -function parseUserWalletCredentials(vprResult: any) { - console.log('PARSING:', vprResult) - - const { - data: { presentation: vp } - } = vprResult - const credentials = Array.isArray(vp.verifiableCredential) ? vp.verifiableCredential : [vp.verifiableCredential] - - const { displayName, displayIcon } = parseLoginDisplayCredential(credentials) - - return { - user: { - id: vp.holder, - displayName, - icon: displayIcon - // session // this will contain the access token and helper methods - } - } -} +// function parseUserWalletCredentials(vprResult: any) { +// console.log('PARSING:', vprResult) + +// const { +// data: { presentation: vp } +// } = vprResult +// const credentials = Array.isArray(vp.verifiableCredential) ? vp.verifiableCredential : [vp.verifiableCredential] + +// const { displayName, displayIcon } = parseLoginDisplayCredential(credentials) + +// return { +// user: { +// id: vp.holder, +// displayName, +// icon: displayIcon +// // session // this will contain the access token and helper methods +// } +// } +// } /** * Parses the user's preferred display name (username) and avatar icon from the diff --git a/packages/common/src/interfaces/AuthUser.ts b/packages/common/src/interfaces/AuthUser.ts index 96b5126f00..a0c2572ab4 100755 --- a/packages/common/src/interfaces/AuthUser.ts +++ b/packages/common/src/interfaces/AuthUser.ts @@ -41,7 +41,7 @@ export const IdentityProviderSeed: IdentityProviderType = { accountIdentifier: '', oauthToken: '', oauthRefreshToken: '', - type: '', + type: 'guest', userId: '' as UserID, createdAt: '', updatedAt: '' diff --git a/packages/common/src/schemas/social/invite.schema.ts b/packages/common/src/schemas/social/invite.schema.ts index bb8016c8ff..67b4e92008 100644 --- a/packages/common/src/schemas/social/invite.schema.ts +++ b/packages/common/src/schemas/social/invite.schema.ts @@ -58,6 +58,8 @@ export const inviteSchema = Type.Object( format: 'uuid' }), token: Type.Optional(Type.String()), + + // @ts-ignore identityProviderType: Type.Optional(StringEnum(identityProviderTypes)), passcode: Type.Optional(Type.String()), targetObjectId: Type.Optional(Type.String()), diff --git a/packages/common/src/schemas/user/generate-token.schema.ts b/packages/common/src/schemas/user/generate-token.schema.ts index 2e0d928c19..9819a83312 100644 --- a/packages/common/src/schemas/user/generate-token.schema.ts +++ b/packages/common/src/schemas/user/generate-token.schema.ts @@ -25,9 +25,10 @@ Ethereal Engine. All Rights Reserved. // For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import type { Static } from '@feathersjs/typebox' -import { getValidator, querySyntax, Type } from '@feathersjs/typebox' +import { getValidator, querySyntax, StringEnum, Type } from '@feathersjs/typebox' import { dataValidator, queryValidator } from '../validators' +import { identityProviderTypes } from './identity-provider.schema' export const generateTokenPath = 'generate-token' @@ -37,7 +38,9 @@ export const generateTokenMethods = ['create'] as const export const generateTokenSchema = Type.Object( { token: Type.String(), - type: Type.String() + + // @ts-ignore + type: Type.Optional(StringEnum(identityProviderTypes)) }, { $id: 'GenerateToken', additionalProperties: false } ) diff --git a/packages/common/src/schemas/user/identity-provider.schema.ts b/packages/common/src/schemas/user/identity-provider.schema.ts index 80943c49be..8b64011316 100644 --- a/packages/common/src/schemas/user/identity-provider.schema.ts +++ b/packages/common/src/schemas/user/identity-provider.schema.ts @@ -46,8 +46,9 @@ export const identityProviderTypes = [ 'facebook', 'twitter', 'linkedin', - 'auth0' -] + 'auth0', + 'guest' +] as const // Main data model schema export const identityProviderSchema = Type.Object( @@ -61,6 +62,8 @@ export const identityProviderSchema = Type.Object( accountIdentifier: Type.Optional(Type.String()), oauthToken: Type.Optional(Type.String()), oauthRefreshToken: Type.Optional(Type.String()), + + // @ts-ignore type: StringEnum(identityProviderTypes), userId: TypedString({ format: 'uuid' diff --git a/packages/server-core/src/user/identity-provider/identity-provider.test.ts b/packages/server-core/src/user/identity-provider/identity-provider.test.ts index 86f7ab341e..1349cdd8bd 100755 --- a/packages/server-core/src/user/identity-provider/identity-provider.test.ts +++ b/packages/server-core/src/user/identity-provider/identity-provider.test.ts @@ -69,7 +69,6 @@ describe('identity-provider.service', () => { assert.equal(createdIdentityProvider.type, type) assert.equal(createdIdentityProvider.token, token) assert.ok(createdIdentityProvider.accessToken) - assert.equal(createdIdentityProvider.userId, userId) }) it('should create an identity provider for email', async () => { diff --git a/patches/@feathersjs+knex+5.0.5.patch b/patches/@feathersjs+knex+5.0.5.patch new file mode 100644 index 0000000000..a9e427d54f --- /dev/null +++ b/patches/@feathersjs+knex+5.0.5.patch @@ -0,0 +1,21 @@ +diff --git a/node_modules/@feathersjs/knex/lib/adapter.js b/node_modules/@feathersjs/knex/lib/adapter.js +index e6851d4..afacfd8 100644 +--- a/node_modules/@feathersjs/knex/lib/adapter.js ++++ b/node_modules/@feathersjs/knex/lib/adapter.js +@@ -125,9 +125,14 @@ class KnexAdapter extends adapter_commons_1.AdapterBase { + } + async _find(params = {}) { + const { filters, paginate } = this.filterQuery(params); +- const { name, id } = this.getOptions(params); ++ const { Model, name, id } = this.getOptions(params); + const builder = params.knex ? params.knex.clone() : this.createQuery(params); +- const countBuilder = builder.clone().clearSelect().clearOrder().count(`${name}.${id} as total`); ++ const countBuilder = Model.count(`* as total`) ++ .with( ++ 'subquery', ++ builder.clone().clearOrder() ++ ) ++ .from('subquery'); + // Handle $limit + if (filters.$limit) { + builder.limit(filters.$limit);