Files
speckle-server/packages/server/modules/auth/repositories/index.ts
T
Kristaps Fabians Geikins bde148f286 chore(server): migrating fully to ESM (#5042)
* wip

* some extra fixes

* stuff kinda works?

* need to figure out mocks

* need to figure out mocks

* fix db listener

* gqlgen fix

* minor gqlgen watch adjustment

* lint fixes

* delete old codegen file

* converting migrations to ESM

* getModuleDIrectory

* vitest sort of works

* added back ts-vitest

* resolve gql double load

* fixing test timeout configs

* TSC lint fix

* fix automate tests

* moar debugging

* debugging

* more debugging

* codegen update

* server works

* yargs migrated

* chore(server): getting rid of global mocks for Server ESM (#5046)

* got rid of email mock

* got rid of comment mocks

* got rid of multi region mocks

* got rid of stripe mock

* admin override mock updated

* removed final mock

* fixing import.meta.resolve calls

* another import.meta.resolve fix

* added requested test

* nyc ESM fix

* removed unneeded deps + linting

* yarn lock forgot to commit

* tryna fix flakyness

* email capture util fix

* sendEmail fix

* fix TSX check

* sender transporter fix + CR comments

* merge main fix

* test fixx

* circleci fix

* gqlgen bigint fix

* error formatter fix

* more error formatting improvements

* esmloader added to Dockerfile

* more dockerfile fixes

* bg jobs fix
2025-07-14 10:26:19 +03:00

93 lines
2.5 KiB
TypeScript

import {
AuthorizationCodes,
RefreshTokens,
Scopes,
ServerAppsScopes,
knex
} from '@/modules/core/dbSchema'
import { InvalidArgumentError } from '@/modules/shared/errors'
import { Nullable } from '@/modules/shared/helpers/typeHelper'
import { ServerAppsScopesRecord } from '@/modules/auth/helpers/types'
import { groupBy, mapValues } from 'lodash-es'
import { TokenScopeData } from '@/modules/shared/domain/rolesAndScopes/types'
import { Knex } from 'knex'
import {
DeleteExistingUserAuthTokens,
GetAppScopes
} from '@/modules/auth/domain/operations'
export type RefreshTokenRecord = {
id: string
tokenDigest: string
appId: string
userId: string
createdAt: string
lifespan: number
}
export type AuthorizationCodeRecord = {
id: string
appId: string
userId: string
challenge: string
createdAt: string
lifespan: number
}
export type ApiTokenRecord = {
id: string
tokenDigest: string
owner: string
name: Nullable<string>
lastChars: Nullable<string>
revoked: boolean
lifespan: number | bigint
createdAt: Date
lastUsed: Date
}
const tables = {
serverAppsScopes: (db: Knex) => db<ServerAppsScopesRecord>(ServerAppsScopes.name),
authorizationCodes: (db: Knex) =>
db<AuthorizationCodeRecord>(AuthorizationCodes.name),
refreshTokens: (db: Knex) => db<RefreshTokenRecord>(RefreshTokens.name)
}
export const deleteExistingAuthTokensFactory =
(deps: { db: Knex }): DeleteExistingUserAuthTokens =>
async (userId: string) => {
if (!userId) throw new InvalidArgumentError('User ID must be set')
await tables.refreshTokens(deps.db).where(RefreshTokens.col.userId, userId).del()
await tables
.authorizationCodes(deps.db)
.where(AuthorizationCodes.col.userId, userId)
.del()
await knex.raw(
`
DELETE FROM api_tokens
WHERE owner = ?
AND id NOT IN (
SELECT p."tokenId" FROM personal_api_tokens p WHERE p."userId" = ?
)
`,
[userId, userId]
)
}
export const getAppScopesFactory =
(deps: { db: Knex }): GetAppScopes =>
async (appIds: string[]) => {
const items = await tables
.serverAppsScopes(deps.db)
.select<Array<ServerAppsScopesRecord & TokenScopeData>>('*')
.whereIn(ServerAppsScopes.col.appId, appIds)
.innerJoin(Scopes.name, Scopes.col.name, ServerAppsScopes.col.scopeName)
// Return record where each key is an app id and the value is an array of scopes
return mapValues(
groupBy(items, (i) => i.appId),
(v) => v.map((vi) => ({ name: vi.scopeName, description: vi.description }))
)
}