feat: added config.json and fileServerMap to the redux
All checks were successful
Open PR on Staging / audit_and_check (pull_request) Successful in 45s

This commit is contained in:
Stixx 2024-12-18 16:18:30 +01:00
parent efc8b9f37a
commit 3de5edfbf6
15 changed files with 168 additions and 9 deletions

3
public/config.json Normal file
View File

@ -0,0 +1,3 @@
{
"SIGIT_BLOSSOM": "https://blossom.sigit.io"
}

View File

@ -17,6 +17,8 @@ import {
saveAuthToken, saveAuthToken,
unixNow unixNow
} from '../utils' } from '../utils'
import { getFileServerMap } from '../utils/file-servers.ts'
import { setServerMapAction } from '../store/servers/action.ts'
export class AuthController { export class AuthController {
private nostrController: NostrController private nostrController: NostrController
@ -78,16 +80,30 @@ export class AuthController {
}) })
) )
const relayMap = await getRelayMap(pubkey) const relayMapPromise = getRelayMap(pubkey)
const serverMapPromise = getFileServerMap(pubkey)
const [relayMap, serverMap] = await Promise.all([
relayMapPromise,
serverMapPromise
])
// Navigate user to relays page if relay map is empty
if (Object.keys(relayMap).length < 1) { if (Object.keys(relayMap).length < 1) {
// Navigate user to relays page if relay map is empty
return Promise.resolve(appPrivateRoutes.relays) return Promise.resolve(appPrivateRoutes.relays)
} }
// Navigate user to servers page if server map is empty
if (Object.keys(serverMap).length < 1) {
return Promise.resolve(appPrivateRoutes.servers)
}
if (store.getState().auth.loggedIn) { if (store.getState().auth.loggedIn) {
if (!compareObjects(store.getState().relays?.map, relayMap.map)) if (!compareObjects(store.getState().relays?.map, relayMap.map))
store.dispatch(setRelayMapAction(relayMap.map)) store.dispatch(setRelayMapAction(relayMap.map))
if (!compareObjects(store.getState().servers?.map, serverMap.map))
store.dispatch(setServerMapAction(serverMap.map))
} }
/** /**

View File

@ -18,7 +18,8 @@ store.subscribe(
auth: store.getState().auth, auth: store.getState().auth,
metadata: store.getState().metadata, metadata: store.getState().metadata,
userRobotImage: store.getState().userRobotImage, userRobotImage: store.getState().userRobotImage,
relays: store.getState().relays relays: store.getState().relays,
servers: store.getState().servers
}) })
}, 1000) }, 1000)
) )

View File

@ -17,10 +17,10 @@ import { useState } from 'react'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { FileServerMap, KeyboardCode } from '../../../types' import { FileServerMap, KeyboardCode } from '../../../types'
import { import {
getFileServers, getFileServerMap,
publishFileServer publishFileServer
} from '../../../utils/file-servers.ts' } from '../../../utils/file-servers.ts'
import { useAppSelector } from '../../../hooks/store.ts' import { useAppSelector } from '../../../hooks'
import { useDidMount } from '../../../hooks' import { useDidMount } from '../../../hooks'
import { SIGIT_BLOSSOM } from '../../../utils' import { SIGIT_BLOSSOM } from '../../../utils'
import axios from 'axios' import axios from 'axios'
@ -48,7 +48,7 @@ export const ServersPage = () => {
const fetchFileServers = async () => { const fetchFileServers = async () => {
if (usersPubkey) { if (usersPubkey) {
await getFileServers(usersPubkey).then((res) => { await getFileServerMap(usersPubkey).then((res) => {
if (res.map) { if (res.map) {
if (Object.keys(res.map).length === 0) { if (Object.keys(res.map).length === 0) {
serverRequirementWarning() serverRequirementWarning()

View File

@ -0,0 +1,54 @@
import axios from 'axios'
import { ILocalConfig } from '../../types/config.ts'
class LocalConfig {
// Static property to hold the single instance of LocalCache
private static instance: LocalConfig | null = null
private config: ILocalConfig
// Private constructor to prevent direct instantiation
private constructor() {
// Set default config
this.config = {
SIGIT_BLOSSOM: 'https://blossom.sigit.io'
}
}
// Method to initialize the database
private async init() {
axios
.get<ILocalConfig>('/config.json')
.then((response) => {
console.log('response', response)
if (typeof response.data === 'object') {
this.config = response.data
} else {
throw 'Failed to load config.json: File not found'
}
})
.catch((error) => {
console.error('Failed to load config.json:', error)
console.warn('Default config will be used.')
})
}
// Static method to get the single instance of LocalCache
public static getInstance(): LocalConfig {
// If the instance doesn't exist, create it
if (!LocalConfig.instance) {
LocalConfig.instance = new LocalConfig()
LocalConfig.instance.init()
}
// Return the single instance of LocalCache
return LocalConfig.instance
}
public getConfig() {
return this.config
}
}
// Export the single instance of LocalCache
export const localConfig = LocalConfig.getInstance()

View File

@ -11,6 +11,9 @@ export const SET_METADATA_EVENT = 'SET_METADATA_EVENT'
export const SET_USER_ROBOT_IMAGE = 'SET_USER_ROBOT_IMAGE' export const SET_USER_ROBOT_IMAGE = 'SET_USER_ROBOT_IMAGE'
export const SET_SERVER_MAP = 'SET_SERVER_MAP'
export const SET_SERVER_MAP_UPDATED = 'SET_SERVER_MAP_UPDATED'
export const SET_RELAY_MAP = 'SET_RELAY_MAP' export const SET_RELAY_MAP = 'SET_RELAY_MAP'
export const SET_RELAY_INFO = 'SET_RELAY_INFO' export const SET_RELAY_INFO = 'SET_RELAY_INFO'
export const SET_RELAY_MAP_UPDATED = 'SET_RELAY_MAP_UPDATED' export const SET_RELAY_MAP_UPDATED = 'SET_RELAY_MAP_UPDATED'

View File

@ -9,15 +9,18 @@ import relaysReducer from './relays/reducer'
import { RelaysDispatchTypes, RelaysState } from './relays/types' import { RelaysDispatchTypes, RelaysState } from './relays/types'
import UserAppDataReducer from './userAppData/reducer' import UserAppDataReducer from './userAppData/reducer'
import userRobotImageReducer from './userRobotImage/reducer' import userRobotImageReducer from './userRobotImage/reducer'
import serversReducer from './servers/reducer'
import { MetadataDispatchTypes } from './metadata/types' import { MetadataDispatchTypes } from './metadata/types'
import { UserAppDataDispatchTypes } from './userAppData/types' import { UserAppDataDispatchTypes } from './userAppData/types'
import { UserRobotImageDispatchTypes } from './userRobotImage/types' import { UserRobotImageDispatchTypes } from './userRobotImage/types'
import { ServersDispatchTypes, ServersState } from './servers/types.ts'
export interface State { export interface State {
auth: AuthState auth: AuthState
metadata?: Event metadata?: Event
userRobotImage?: string userRobotImage?: string
relays: RelaysState relays: RelaysState
servers: ServersState
userAppData?: UserAppData userAppData?: UserAppData
} }
@ -26,6 +29,7 @@ type AppActions =
| MetadataDispatchTypes | MetadataDispatchTypes
| UserRobotImageDispatchTypes | UserRobotImageDispatchTypes
| RelaysDispatchTypes | RelaysDispatchTypes
| ServersDispatchTypes
| UserAppDataDispatchTypes | UserAppDataDispatchTypes
export const appReducer = combineReducers({ export const appReducer = combineReducers({
@ -33,6 +37,7 @@ export const appReducer = combineReducers({
metadata: metadataReducer, metadata: metadataReducer,
userRobotImage: userRobotImageReducer, userRobotImage: userRobotImageReducer,
relays: relaysReducer, relays: relaysReducer,
servers: serversReducer,
userAppData: UserAppDataReducer userAppData: UserAppDataReducer
}) })

View File

@ -0,0 +1,12 @@
import * as ActionTypes from '../actionTypes'
import { SetServerMapAction, SetServerMapUpdatedAction } from './types'
import { ServerMap } from '../../types'
export const setServerMapAction = (payload: ServerMap): SetServerMapAction => ({
type: ActionTypes.SET_SERVER_MAP,
payload
})
export const setServerMapUpdatedAction = (): SetServerMapUpdatedAction => ({
type: ActionTypes.SET_SERVER_MAP_UPDATED
})

View File

@ -0,0 +1,28 @@
import * as ActionTypes from '../actionTypes'
import { ServersDispatchTypes, ServersState } from './types'
const initialState: ServersState = {
map: undefined,
mapUpdated: undefined
}
const reducer = (
state = initialState,
action: ServersDispatchTypes
): ServersState => {
switch (action.type) {
case ActionTypes.SET_SERVER_MAP:
return { ...state, map: action.payload, mapUpdated: Date.now() }
case ActionTypes.SET_SERVER_MAP_UPDATED:
return { ...state, mapUpdated: Date.now() }
case ActionTypes.RESTORE_STATE:
return action.payload.servers || initialState
default:
return state
}
}
export default reducer

View File

@ -0,0 +1,22 @@
import * as ActionTypes from '../actionTypes'
import { RestoreState } from '../actions'
import { ServerMap } from '../../types'
export type ServersState = {
map?: ServerMap
mapUpdated?: number
}
export interface SetServerMapAction {
type: typeof ActionTypes.SET_SERVER_MAP
payload: ServerMap
}
export interface SetServerMapUpdatedAction {
type: typeof ActionTypes.SET_SERVER_MAP_UPDATED
}
export type ServersDispatchTypes =
| SetServerMapAction
| SetServerMapUpdatedAction
| RestoreState

3
src/types/config.ts Normal file
View File

@ -0,0 +1,3 @@
export interface ILocalConfig {
SIGIT_BLOSSOM: string
}

View File

@ -5,4 +5,5 @@ export * from './profile'
export * from './relay' export * from './relay'
export * from './zip' export * from './zip'
export * from './event' export * from './event'
export * from './server'
export * from './file-server.ts' export * from './file-server.ts'

6
src/types/server.ts Normal file
View File

@ -0,0 +1,6 @@
export type ServerMap = {
[key: string]: {
read: boolean
write: boolean
}
}

View File

@ -1,7 +1,12 @@
import { localConfig } from '../services/config'
import { ILocalConfig } from '../types/config.ts'
export const EMPTY: string = '' export const EMPTY: string = ''
export const ARRAY_BUFFER = 'arraybuffer' export const ARRAY_BUFFER = 'arraybuffer'
export const DEFLATE = 'DEFLATE' export const DEFLATE = 'DEFLATE'
const config: ILocalConfig = localConfig.getConfig()
/** /**
* Number of milliseconds in one week. * Number of milliseconds in one week.
*/ */
@ -14,7 +19,7 @@ export const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000
export const SIGIT_RELAY = 'wss://relay.sigit.io' export const SIGIT_RELAY = 'wss://relay.sigit.io'
export const SIGIT_BLOSSOM = 'https://blossom.sigit.io' export const SIGIT_BLOSSOM = config.SIGIT_BLOSSOM
export const DEFAULT_LOOK_UP_RELAY_LIST = [ export const DEFAULT_LOOK_UP_RELAY_LIST = [
SIGIT_RELAY, SIGIT_RELAY,

View File

@ -8,7 +8,7 @@ import { Filter, UnsignedEvent, kinds } from 'nostr-tools'
* Fetches the relays to get preferred file servers for the given npub * Fetches the relays to get preferred file servers for the given npub
* @param npub hex pubkey * @param npub hex pubkey
*/ */
const getFileServers = async ( const getFileServerMap = async (
npub: string npub: string
): Promise<{ map: FileServerMap; mapUpdated?: number }> => { ): Promise<{ map: FileServerMap; mapUpdated?: number }> => {
// More info about this kind of event available https://github.com/nostr-protocol/nips/blob/master/96.md // More info about this kind of event available https://github.com/nostr-protocol/nips/blob/master/96.md
@ -112,4 +112,4 @@ const getDefaultFileServerMap = (): FileServerMap => ({
[SIGIT_BLOSSOM]: { write: true, read: true } [SIGIT_BLOSSOM]: { write: true, read: true }
}) })
export { getFileServers, publishFileServer } export { getFileServerMap, publishFileServer }