Skip to content

Commit 94e7c2c

Browse files
author
Codex Agent
committed
feat(auth): allow user-specific permissions
1 parent 276ba48 commit 94e7c2c

5 files changed

Lines changed: 620 additions & 609 deletions

File tree

packages/types/lib/config.d.ts

Lines changed: 187 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,215 @@
1-
import type { LogLevelNames } from 'loglevel'
2-
import type { DialogProps } from '@mui/material'
3-
import type { UiconsIndex } from 'uicons.js'
4-
5-
import { Props as ImgProps } from '@components/Img'
6-
7-
import type { CustomComponent } from './blocks'
8-
import config = require('../../../config/default.json')
9-
import example = require('../../../config/local.example.json')
10-
11-
import type { Schema } from './server'
12-
import {
13-
OnlyType,
14-
DeepMerge,
15-
ComparisonReport,
16-
Paths,
17-
ObjectPathValue,
18-
} from './utility'
19-
import { Strategy } from './general'
20-
import { TileLayer } from './client'
21-
1+
import type { LogLevelNames } from 'loglevel'
2+
import type { DialogProps } from '@mui/material'
3+
import type { UiconsIndex } from 'uicons.js'
4+
5+
import { Props as ImgProps } from '@components/Img'
6+
7+
import type { CustomComponent } from './blocks'
8+
import config = require('../../../config/default.json')
9+
import example = require('../../../config/local.example.json')
10+
11+
import type { Schema } from './server'
12+
import {
13+
OnlyType,
14+
DeepMerge,
15+
ComparisonReport,
16+
Paths,
17+
ObjectPathValue,
18+
} from './utility'
19+
import { Strategy } from './general'
20+
import { TileLayer } from './client'
21+
2222
type BaseConfig = typeof config
2323
type ExampleConfig = typeof example
2424

25+
/** Discord role ID or user ID that can gate access to resources */
26+
type AuthIdentifier = string
27+
2528
export type ConfigAreas = Awaited<
2629
ReturnType<(typeof import('server/src/services/areas'))['loadLatestAreas']>
2730
>
28-
29-
export type Config<Client extends boolean = false> = DeepMerge<
30-
Omit<BaseConfig, 'icons' | 'manualAreas'>,
31-
{
32-
client: Client extends true
33-
? {
34-
version: string
35-
locales: string[]
36-
localeStatus: ReturnType<
37-
(typeof import('@rm/locales/lib/utils'))['getStatus']
38-
>
39-
hasCustom: boolean
40-
title: string
41-
}
42-
: never
43-
webhooks: Webhook[]
44-
tileServers: TileLayer[]
45-
devOptions: {
46-
logLevel: LogLevelNames
47-
skipUpdateCheck?: boolean
48-
}
49-
defaultFilters: {
50-
s2cells: {
51-
cells: number[]
52-
}
53-
}
54-
areas: ConfigAreas
31+
32+
export type Config<Client extends boolean = false> = DeepMerge<
33+
Omit<BaseConfig, 'icons' | 'manualAreas'>,
34+
{
35+
client: Client extends true
36+
? {
37+
version: string
38+
locales: string[]
39+
localeStatus: ReturnType<
40+
(typeof import('@rm/locales/lib/utils'))['getStatus']
41+
>
42+
hasCustom: boolean
43+
title: string
44+
}
45+
: never
46+
webhooks: Webhook[]
47+
tileServers: TileLayer[]
48+
devOptions: {
49+
logLevel: LogLevelNames
50+
skipUpdateCheck?: boolean
51+
}
52+
defaultFilters: {
53+
s2cells: {
54+
cells: number[]
55+
}
56+
}
57+
areas: ConfigAreas
5558
authentication: {
56-
areaRestrictions: { roles: string[]; areas: string[] }[]
57-
// Unfortunately these types are not convenient for looping the `perms` object...
58-
// excludeFromTutorial: (keyof BaseConfig['authentication']['perms'])[]
59-
// alwaysEnabledPerms: (keyof BaseConfig['authentication']['perms'])[]
60-
excludeFromTutorial: string[]
61-
alwaysEnabledPerms: string[]
62-
aliases: { role: string | string[]; name: string }[]
63-
methods: Strategy[]
64-
strategies: {
65-
type: Strategy
59+
areaRestrictions: { roles: AuthIdentifier[]; areas: string[] }[]
60+
// Unfortunately these types are not convenient for looping the `perms` object...
61+
// excludeFromTutorial: (keyof BaseConfig['authentication']['perms'])[]
62+
// alwaysEnabledPerms: (keyof BaseConfig['authentication']['perms'])[]
63+
excludeFromTutorial: string[]
64+
alwaysEnabledPerms: string[]
65+
aliases: { role: AuthIdentifier | AuthIdentifier[]; name: string }[]
66+
methods: Strategy[]
67+
strategies: {
68+
type: Strategy
6669
trialPeriod: {
6770
start: TrialPeriodDate
6871
end: TrialPeriodDate
69-
roles: string[]
72+
roles: AuthIdentifier[]
7073
}
71-
allowedGuilds: string[]
72-
blockedGuilds: string[]
73-
allowedUsers: string[]
74-
}[]
75-
perms: {
76-
[K in keyof BaseConfig['authentication']['perms']]: Omit<
77-
BaseConfig['authentication']['perms'][K],
78-
'roles'
79-
> & { roles: string[] }
80-
}
81-
}
82-
api: {
83-
pvp: {
84-
leagues: {
85-
minRank?: number
86-
maxRank?: number
87-
littleCupRules?: boolean
88-
}[]
89-
leagueObj: {
90-
[key in BaseConfig['api']['pvp']['leagues'][number]['name']]:
91-
| number
92-
| { little: false; cap: number }
93-
}
94-
}
95-
}
96-
map: {
97-
domain?: string
98-
misc: {
99-
/** @deprecated */
100-
distance?: string
101-
}
102-
messageOfTheDay: {
103-
settings: {
104-
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
105-
}
106-
titles: string[]
107-
components: CustomComponent[]
108-
footerButtons: CustomComponent[]
109-
dialogMaxWidth: DialogProps['maxWidth']
110-
}
111-
donationPage: {
112-
settings: {
113-
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
114-
}
115-
titles: string[]
116-
components: CustomComponent[]
117-
footerButtons: CustomComponent[]
118-
}
119-
loginPage: {
120-
settings: {
121-
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
122-
}
123-
components: CustomComponent[]
124-
}
125-
}
126-
multiDomains: MultiDomain[]
127-
multiDomainsObj: Record<string, MultiDomain>
128-
database: {
129-
schemas: Schema[]
130-
settings: {
131-
extraUserFields: (ExtraField | string)[]
74+
allowedGuilds: string[]
75+
blockedGuilds: string[]
76+
allowedUsers: string[]
77+
}[]
78+
perms: {
79+
[K in keyof BaseConfig['authentication']['perms']]: Omit<
80+
BaseConfig['authentication']['perms'][K],
81+
'roles'
82+
> & { roles: AuthIdentifier[] }
13283
}
13384
}
85+
api: {
86+
pvp: {
87+
leagues: {
88+
minRank?: number
89+
maxRank?: number
90+
littleCupRules?: boolean
91+
}[]
92+
leagueObj: {
93+
[key in BaseConfig['api']['pvp']['leagues'][number]['name']]:
94+
| number
95+
| { little: false; cap: number }
96+
}
97+
}
98+
}
99+
map: {
100+
domain?: string
101+
misc: {
102+
/** @deprecated */
103+
distance?: string
104+
}
105+
messageOfTheDay: {
106+
settings: {
107+
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
108+
}
109+
titles: string[]
110+
components: CustomComponent[]
111+
footerButtons: CustomComponent[]
112+
dialogMaxWidth: DialogProps['maxWidth']
113+
}
114+
donationPage: {
115+
settings: {
116+
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
117+
}
118+
titles: string[]
119+
components: CustomComponent[]
120+
footerButtons: CustomComponent[]
121+
}
122+
loginPage: {
123+
settings: {
124+
parentStyle: Record<string, string> // should be CSS properties but performance seems to die
125+
}
126+
components: CustomComponent[]
127+
}
128+
}
129+
multiDomains: MultiDomain[]
130+
multiDomainsObj: Record<string, MultiDomain>
131+
database: {
132+
schemas: Schema[]
133+
settings: {
134+
extraUserFields: (ExtraField | string)[]
135+
}
136+
}
134137
scanner: {
135138
scanNext: {
136-
discordRoles: string[]
139+
discordRoles: AuthIdentifier[]
137140
telegramGroups: string[]
138141
local: string[]
139142
}
140143
scanZone: {
141-
discordRoles: string[]
144+
discordRoles: AuthIdentifier[]
142145
telegramGroups: string[]
143146
local: string[]
144147
}
145148
}
146-
icons: Icons
147-
manualAreas: ExampleConfig['manualAreas'][number][]
148-
}
149-
>
150-
151-
// unclear why this is needed, but it is for the MultiDomain type to parse...
152-
type Map = Config['map']
153-
154-
export interface MultiDomain extends Map {
155-
domain: string
156-
}
157-
158-
export interface Icons extends Omit<BaseConfig['icons'], 'styles'> {
159-
customizable: string[]
160-
styles: (ExampleConfig['icons']['styles'][number] & {
161-
data?: UiconsIndex
162-
})[]
163-
defaultIcons: Record<string, string>
164-
}
165-
166-
export type StrategyConfig = Config['authentication']['strategies'][number]
167-
168-
export interface TrialPeriodDate {
169-
year?: number
170-
month?: number
171-
day?: number
172-
hour?: number
173-
minute?: number
174-
second?: number
175-
millisecond?: number
176-
}
177-
178-
export interface ExtraField {
179-
name: string
180-
database: string
181-
disabled: boolean
182-
}
183-
184-
export interface Webhook {
185-
enabled: boolean
186-
provider: 'poracle'
187-
name: string
188-
host: string
189-
port: number
190-
poracleSecret: string
191-
addressFormat?: string
192-
nominatimUrl?: string
149+
icons: Icons
150+
manualAreas: ExampleConfig['manualAreas'][number][]
151+
}
152+
>
153+
154+
// unclear why this is needed, but it is for the MultiDomain type to parse...
155+
type Map = Config['map']
156+
157+
export interface MultiDomain extends Map {
158+
domain: string
159+
}
160+
161+
export interface Icons extends Omit<BaseConfig['icons'], 'styles'> {
162+
customizable: string[]
163+
styles: (ExampleConfig['icons']['styles'][number] & {
164+
data?: UiconsIndex
165+
})[]
166+
defaultIcons: Record<string, string>
167+
}
168+
169+
export type StrategyConfig = Config['authentication']['strategies'][number]
170+
171+
export interface TrialPeriodDate {
172+
year?: number
173+
month?: number
174+
day?: number
175+
hour?: number
176+
minute?: number
177+
second?: number
178+
millisecond?: number
179+
}
180+
181+
export interface ExtraField {
182+
name: string
183+
database: string
184+
disabled: boolean
185+
}
186+
187+
export interface Webhook {
188+
enabled: boolean
189+
provider: 'poracle'
190+
name: string
191+
host: string
192+
port: number
193+
poracleSecret: string
194+
addressFormat?: string
195+
nominatimUrl?: string
193196
trialPeriodEligible?: boolean
194197
areasToSkip: string[]
195-
discordRoles: []
198+
discordRoles: AuthIdentifier[]
196199
telegramGroups: []
197200
local: []
198201
}
199-
200-
export interface GridSizes {
201-
xs?: number
202-
sm?: number
203-
md?: number
204-
lg?: number
205-
xl?: number
206-
}
207-
208-
export type GetSafeConfig = <P extends Paths<Config>>(
209-
path: P,
210-
) => ObjectPathValue<Config, P>
211-
212-
export type ConfigEqualReport = ComparisonReport<Omit<Config, 'areas'>>
202+
203+
export interface GridSizes {
204+
xs?: number
205+
sm?: number
206+
md?: number
207+
lg?: number
208+
xl?: number
209+
}
210+
211+
export type GetSafeConfig = <P extends Paths<Config>>(
212+
path: P,
213+
) => ObjectPathValue<Config, P>
214+
215+
export type ConfigEqualReport = ComparisonReport<Omit<Config, 'areas'>>

0 commit comments

Comments
 (0)