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/analytics/analytics/analytics.hooks.ts b/packages/server-core/src/analytics/analytics/analytics.hooks.ts index bbc5c56837..54d867bfcb 100755 --- a/packages/server-core/src/analytics/analytics/analytics.hooks.ts +++ b/packages/server-core/src/analytics/analytics/analytics.hooks.ts @@ -117,7 +117,7 @@ export default { before: { all: [ iff(isProvider('external'), verifyScope('admin', 'admin')), - () => schemaHooks.validateQuery(analyticsQueryValidator), + schemaHooks.validateQuery(analyticsQueryValidator), schemaHooks.resolveQuery(analyticsQueryResolver) ], find: [ @@ -126,9 +126,9 @@ export default { discardQuery('action') ], get: [], - create: [() => schemaHooks.validateData(analyticsDataValidator), schemaHooks.resolveData(analyticsDataResolver)], + create: [schemaHooks.validateData(analyticsDataValidator), schemaHooks.resolveData(analyticsDataResolver)], update: [], - patch: [() => schemaHooks.validateData(analyticsPatchValidator), schemaHooks.resolveData(analyticsPatchResolver)], + patch: [schemaHooks.validateData(analyticsPatchValidator), schemaHooks.resolveData(analyticsPatchResolver)], remove: [] }, diff --git a/packages/server-core/src/projects/project/project-helper.ts b/packages/server-core/src/projects/project/project-helper.ts index 887ddbdd04..fe7121309d 100644 --- a/packages/server-core/src/projects/project/project-helper.ts +++ b/packages/server-core/src/projects/project/project-helper.ts @@ -1678,6 +1678,19 @@ const staticResourceClasses = [ AssetType.Prefab ] +const ignoreFiles = ['.ds_store'] + +/** + * Checks whether a file is to be ignored in resources.json and static-resources + * @param key + */ +export const isIgnoredFile = (key: string) => { + for (const ignoreFile of ignoreFiles) { + if (key.includes(ignoreFile)) return true + } + return false +} + /** * Updates the local storage provider with the project's current files * @param app Application object @@ -1757,7 +1770,10 @@ export const uploadLocalProjectToProvider = async ( }, { isDirectory: false } ) - if (!filePathRelative.startsWith(`assets/`) && !filePathRelative.startsWith(`public/`)) { + if ( + (!filePathRelative.startsWith(`assets/`) && !filePathRelative.startsWith(`public/`)) || + isIgnoredFile(filePathRelative) + ) { existingKeySet.delete(key) continue } diff --git a/packages/server-core/src/user/identity-provider/identity-provider.hooks.ts b/packages/server-core/src/user/identity-provider/identity-provider.hooks.ts index 787a24f480..0ba3d4f27a 100755 --- a/packages/server-core/src/user/identity-provider/identity-provider.hooks.ts +++ b/packages/server-core/src/user/identity-provider/identity-provider.hooks.ts @@ -209,7 +209,7 @@ async function addIdentityProviderType(context: HookContext) { /* (AFTER) CREATE HOOKS */ async function addScopes(context: HookContext) { - if (isDev && (context.actualData as IdentityProviderType).type === 'admin') { + if (isDev && context.isAdmin === true) { // in dev mode, add all scopes to the first user made an admin const scopeTypes = await context.app.service(scopeTypePath).find({ paginate: false 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/packages/server-core/src/world/spawn-point/spawn-point.hooks.ts b/packages/server-core/src/world/spawn-point/spawn-point.hooks.ts index 18a6200c58..837edb9d43 100644 --- a/packages/server-core/src/world/spawn-point/spawn-point.hooks.ts +++ b/packages/server-core/src/world/spawn-point/spawn-point.hooks.ts @@ -43,25 +43,22 @@ export default createSkippableHooks( all: [schemaHooks.resolveExternal(spawnPointExternalResolver), schemaHooks.resolveResult(spawnPointResolver)] }, before: { - all: [ - () => schemaHooks.validateQuery(spawnPointQueryValidator), - schemaHooks.resolveQuery(spawnPointQueryResolver) - ], + all: [schemaHooks.validateQuery(spawnPointQueryValidator), schemaHooks.resolveQuery(spawnPointQueryResolver)], find: [enableClientPagination()], get: [], create: [ iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false)), - () => schemaHooks.validateData(spawnPointDataValidator), + schemaHooks.validateData(spawnPointDataValidator), schemaHooks.resolveData(spawnPointDataResolver) ], update: [ iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false)), - () => schemaHooks.validateData(spawnPointDataValidator), + schemaHooks.validateData(spawnPointDataValidator), schemaHooks.resolveData(spawnPointDataResolver) ], patch: [ iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false)), - () => schemaHooks.validateData(spawnPointDataValidator), + schemaHooks.validateData(spawnPointDataValidator), schemaHooks.resolveData(spawnPointDataResolver) ], remove: [iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false))] diff --git a/packages/ui/src/primitives/tailwind/Button/index.tsx b/packages/ui/src/primitives/tailwind/Button/index.tsx index 31641e2262..8daeef8fec 100644 --- a/packages/ui/src/primitives/tailwind/Button/index.tsx +++ b/packages/ui/src/primitives/tailwind/Button/index.tsx @@ -90,8 +90,8 @@ const Button = React.forwardRef( sizes[size], fullWidth ? 'w-full' : 'w-fit', roundedTypes[rounded], - variants[variant], disabled ? 'bg-[#F3F4F6] text-[#9CA3AF] dark:bg-[#5F7DBF] dark:text-[#FFFFFF]' : '', + variants[variant], className ) 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);