Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Updated JWT authentication to handle RSA signatures
Browse files Browse the repository at this point in the history
New authentication-setting fields for JWT algorithm and JWT public key.
Keys should be inserted as strings with '\n' replacing new lines.

Replaced the last of the API.instance.client uses with Engine.instance.api

Added a new service that will return the JWT public key.

Replaced current jsonwebtoken.decode calls with jsonwebtoken.verify.
decode does not check if the signature is valid.

Resolves IR-3827
  • Loading branch information
barankyle committed Aug 14, 2024
1 parent bce156b commit 03c36e4
Show file tree
Hide file tree
Showing 25 changed files with 472 additions and 92 deletions.
2 changes: 2 additions & 0 deletions packages/client-core/i18n/en/admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@
"service": "Service",
"githubAppId": "App ID (Enter for GitHub App, omit for OAuth App)",
"secret": "Secret",
"jwtAlgorithm": "JWT Algorithm",
"jwtPublicKey": "JWT Public Key",
"entity": "Entity",
"authStrategies": "Authentication Strategies",
"userName": "User Name",
Expand Down
9 changes: 2 additions & 7 deletions packages/client-core/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export type FeathersClient = FeathersApplication<ServiceTypes> &
/**@deprecated - use 'Engine.instance.api' instead */
export class API {
/**@deprecated - use 'Engine.instance.api' instead */
static instance: API
static instance
client: FeathersClient

static createAPI = () => {
Expand All @@ -61,13 +61,8 @@ export class API {
})
)

primus.on('reconnected', () => API.instance.client.reAuthenticate(true))

API.instance = new API()
API.instance.client = feathersClient as any
primus.on('reconnected', () => feathersClient.reAuthenticate(true))

Engine.instance.api = feathersClient
}
}

globalThis.API = API
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,20 @@ const AuthenticationTab = forwardRef(({ open }: { open: boolean }, ref: React.Mu
/>

<Input
className="col-span-1"
label={t('admin:components.setting.entity')}
value={authSetting?.entity || ''}
disabled
/>

<Input
className="col-span-1"
label={t('admin:components.setting.jwtAlgorithm')}
value={authSetting?.jwtAlgorithm || ''}
disabled
/>

<PasswordInput
className="col-span-1"
label={t('admin:components.setting.secret')}
value={authSetting?.secret || ''}
Expand All @@ -207,8 +221,8 @@ const AuthenticationTab = forwardRef(({ open }: { open: boolean }, ref: React.Mu

<Input
className="col-span-1"
label={t('admin:components.setting.entity')}
value={authSetting?.entity || ''}
label={t('admin:components.setting.jwtPublicKey')}
value={authSetting?.jwtPublicKey || ''}
disabled
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ import { createRoot } from 'react-dom/client'

import { ChannelID, MessageID, UserID } from '@etherealengine/common/src/schema.type.module'
import { createEngine } from '@etherealengine/ecs'
import { Engine } from '@etherealengine/ecs/src/Engine'
import { getMutableState } from '@etherealengine/hyperflux'

import { InstanceChat } from '.'
import { createDOM } from '../../../tests/createDOM'
import { createMockAPI } from '../../../tests/createMockAPI'
import { API } from '../../API'
import { ChannelState } from '../../social/services/ChannelService'

describe('Instance Chat Component', () => {
Expand All @@ -46,7 +46,7 @@ describe('Instance Chat Component', () => {
rootContainer = document.createElement('div')
document.body.appendChild(rootContainer)
createEngine()
API.instance = createMockAPI()
Engine.instance.api = createMockAPI()
})

afterEach(() => {
Expand Down
9 changes: 4 additions & 5 deletions packages/client-core/src/social/services/LocationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { Engine } from '@etherealengine/ecs/src/Engine'
import { defineState, getMutableState, getState } from '@etherealengine/hyperflux'

import { useEffect } from 'react'
import { API } from '../../API'
import { NotificationService } from '../../common/services/NotificationService'
import { AuthState } from '../../user/services/AuthService'

Expand Down Expand Up @@ -141,15 +140,15 @@ export const LocationService = {
getLocation: async (locationId: LocationID) => {
try {
LocationState.fetchingCurrentSocialLocation()
const location = await API.instance.client.service(locationPath).get(locationId)
const location = await Engine.instance.api.service(locationPath).get(locationId)
LocationState.socialLocationRetrieved(location)
} catch (err) {
NotificationService.dispatchNotify(err.message, { variant: 'error' })
}
},
getLocationByName: async (locationName: string) => {
LocationState.fetchingCurrentSocialLocation()
const locationResult = (await API.instance.client.service(locationPath).find({
const locationResult = (await Engine.instance.api.service(locationPath).find({
query: {
slugifiedName: locationName
}
Expand All @@ -167,7 +166,7 @@ export const LocationService = {
}
},
getLobby: async () => {
const lobbyResult = (await API.instance.client.service(locationPath).find({
const lobbyResult = (await Engine.instance.api.service(locationPath).find({
query: {
isLobby: true,
$limit: 1
Expand All @@ -182,7 +181,7 @@ export const LocationService = {
},
banUserFromLocation: async (userId: UserID, locationId: LocationID) => {
try {
await API.instance.client.service(locationBanPath).create({
await Engine.instance.api.service(locationBanPath).create({
userId: userId,
locationId: locationId
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'

import { locationPath, LocationType } from '@etherealengine/common/src/schema.type.module'
import { Engine } from '@etherealengine/ecs/src/Engine'
import Button from '@etherealengine/ui/src/primitives/mui/Button'
import Icon from '@etherealengine/ui/src/primitives/mui/Icon'
import InputAdornment from '@etherealengine/ui/src/primitives/mui/InputAdornment'
Expand All @@ -40,7 +41,6 @@ import TableRow from '@etherealengine/ui/src/primitives/mui/TableRow'
import TextField from '@etherealengine/ui/src/primitives/mui/TextField'
import Typography from '@etherealengine/ui/src/primitives/mui/Typography'

import { API } from '../../../../API'
import { LocationSeed } from '../../../../social/services/LocationService'
import styles from '../index.module.scss'

Expand Down Expand Up @@ -68,7 +68,7 @@ const LocationMenu = (props: Props) => {
}, [])

const fetchLocations = (page: number, rows: number, search?: string) => {
API.instance.client
Engine.instance.api
.service(locationPath)
.find({
query: {
Expand Down
Loading

0 comments on commit 03c36e4

Please sign in to comment.