chore(server): auth IoC 5 - createAppFactory
This commit is contained in:
Родитель
c1dbbe9d7d
Коммит
22253cd874
|
@ -5,6 +5,9 @@ import {
|
|||
UserServerApp
|
||||
} from '@/modules/auth/domain/types'
|
||||
import { ScopeRecord } from '@/modules/auth/helpers/types'
|
||||
import { ServerAppRecord } from '@/modules/core/helpers/types'
|
||||
import { MarkNullableOptional } from '@/modules/shared/helpers/typeHelper'
|
||||
import { ServerScope } from '@speckle/shared'
|
||||
|
||||
export type GetApp = (params: { id: string }) => Promise<FullServerApp | null>
|
||||
|
||||
|
@ -27,4 +30,13 @@ export type UpdateDefaultApp = (
|
|||
existingApp: FullServerApp
|
||||
) => Promise<void>
|
||||
|
||||
export type CreateApp = (
|
||||
app: Omit<
|
||||
MarkNullableOptional<ServerAppRecord>,
|
||||
'id' | 'secret' | 'createdAt' | 'trustByDefault'
|
||||
> & {
|
||||
scopes: ServerScope[]
|
||||
}
|
||||
) => Promise<{ id: string; secret: string }>
|
||||
|
||||
export type InitializeDefaultApps = () => Promise<void>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const { ForbiddenError } = require('@/modules/shared/errors')
|
||||
const {
|
||||
createApp,
|
||||
updateApp,
|
||||
deleteApp,
|
||||
revokeExistingAppCredentialsForUser
|
||||
|
@ -10,7 +9,8 @@ const {
|
|||
getAppFactory,
|
||||
getAllPublicAppsFactory,
|
||||
getAllAppsCreatedByUserFactory,
|
||||
getAllAppsAuthorizedByUserFactory
|
||||
getAllAppsAuthorizedByUserFactory,
|
||||
createAppFactory
|
||||
} = require('@/modules/auth/repositories/apps')
|
||||
const { db } = require('@/db/knex')
|
||||
|
||||
|
@ -18,6 +18,7 @@ const getApp = getAppFactory({ db })
|
|||
const getAllPublicApps = getAllPublicAppsFactory({ db })
|
||||
const getAllAppsCreatedByUser = getAllAppsCreatedByUserFactory({ db })
|
||||
const getAllAppsAuthorizedByUser = getAllAppsAuthorizedByUserFactory({ db })
|
||||
const createApp = createAppFactory({ db })
|
||||
|
||||
module.exports = {
|
||||
Query: {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { moduleLogger } from '@/logging/logging'
|
||||
import { getDefaultApp } from '@/modules/auth/defaultApps'
|
||||
import {
|
||||
CreateApp,
|
||||
GetAllAppsAuthorizedByUser,
|
||||
GetAllAppsCreatedByUser,
|
||||
GetAllPublicApps,
|
||||
|
@ -24,6 +25,7 @@ import {
|
|||
UserServerAppTokens
|
||||
} from '@/modules/core/dbSchema'
|
||||
import { ServerAppRecord, UserRecord } from '@/modules/core/helpers/types'
|
||||
import cryptoRandomString from 'crypto-random-string'
|
||||
import { Knex } from 'knex'
|
||||
import { difference, omit } from 'lodash'
|
||||
|
||||
|
@ -242,3 +244,28 @@ export const updateDefaultAppFactory =
|
|||
.transacting(trx)
|
||||
})
|
||||
}
|
||||
|
||||
export const createAppFactory =
|
||||
(deps: { db: Knex }): CreateApp =>
|
||||
async (app) => {
|
||||
const id = cryptoRandomString({ length: 10 })
|
||||
const secret = cryptoRandomString({ length: 10 })
|
||||
const scopes = (app.scopes || []).filter((s) => !!s?.length)
|
||||
|
||||
if (!scopes.length) {
|
||||
throw new Error('Cannot create an app with no scopes.')
|
||||
}
|
||||
|
||||
const insertableApp = {
|
||||
...omit(app, ['scopes', 'firstparty', 'trustByDefault']),
|
||||
id,
|
||||
secret
|
||||
}
|
||||
|
||||
await tables.serverApps(deps.db).insert(insertableApp)
|
||||
await tables
|
||||
.serverAppsScopes(deps.db)
|
||||
.insert(scopes.map((s) => ({ appId: id, scopeName: s })))
|
||||
|
||||
return { id, secret }
|
||||
}
|
||||
|
|
|
@ -14,27 +14,6 @@ const AuthorizationCodes = () => knex('authorization_codes')
|
|||
const RefreshTokens = () => knex('refresh_tokens')
|
||||
|
||||
module.exports = {
|
||||
async createApp(app) {
|
||||
app.id = crs({ length: 10 })
|
||||
app.secret = crs({ length: 10 })
|
||||
|
||||
const scopes = (app.scopes || []).filter((s) => !!s?.length)
|
||||
|
||||
if (!scopes.length) {
|
||||
throw new Error('Cannot create an app with no scopes.')
|
||||
}
|
||||
|
||||
delete app.scopes
|
||||
delete app.firstparty
|
||||
delete app.trustByDefault
|
||||
|
||||
await ServerApps().insert(app)
|
||||
await ServerAppsScopes().insert(
|
||||
scopes.map((s) => ({ appId: app.id, scopeName: s }))
|
||||
)
|
||||
return { id: app.id, secret: app.secret }
|
||||
},
|
||||
|
||||
async updateApp({ app }) {
|
||||
// any app update should nuke everything and force users to re-authorize it.
|
||||
await module.exports.revokeExistingAppCredentials({ appId: app.id })
|
||||
|
|
|
@ -5,7 +5,6 @@ const { createUser } = require(`@/modules/core/services/users`)
|
|||
const { validateToken } = require(`@/modules/core/services/tokens`)
|
||||
const { beforeEachContext } = require(`@/test/hooks`)
|
||||
const {
|
||||
createApp,
|
||||
updateApp,
|
||||
deleteApp,
|
||||
createAuthorizationCode,
|
||||
|
@ -20,12 +19,14 @@ const cryptoRandomString = require('crypto-random-string')
|
|||
const {
|
||||
getAppFactory,
|
||||
updateDefaultAppFactory,
|
||||
getAllPublicAppsFactory
|
||||
getAllPublicAppsFactory,
|
||||
createAppFactory
|
||||
} = require('@/modules/auth/repositories/apps')
|
||||
|
||||
const getApp = getAppFactory({ db: knex })
|
||||
const updateDefaultApp = updateDefaultAppFactory({ db: knex })
|
||||
const getAllPublicApps = getAllPublicAppsFactory({ db: knex })
|
||||
const createApp = createAppFactory({ db: knex })
|
||||
|
||||
describe('Services @apps-services', () => {
|
||||
const actor = {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { createApp } from '@/modules/auth/services/apps'
|
||||
import { TokenResourceIdentifierType } from '@/modules/core/graph/generated/graphql'
|
||||
import { createAppToken } from '@/modules/core/services/tokens'
|
||||
import { BasicTestUser, createTestUsers } from '@/test/authHelper'
|
||||
|
@ -25,6 +24,10 @@ import cryptoRandomString from 'crypto-random-string'
|
|||
import { difference } from 'lodash'
|
||||
import type { Express } from 'express'
|
||||
import request from 'supertest'
|
||||
import { createAppFactory } from '@/modules/auth/repositories/apps'
|
||||
import { db } from '@/db/knex'
|
||||
|
||||
const createApp = createAppFactory({ db })
|
||||
|
||||
/**
|
||||
* Older API token test cases can be found in `graph.spec.js`
|
||||
|
@ -198,7 +201,8 @@ describe('API Tokens', () => {
|
|||
name: cryptoRandomString({ length: 10 }),
|
||||
public: true,
|
||||
scopes: AllScopes,
|
||||
redirectUrl: 'http://127.0.0.1:1337'
|
||||
redirectUrl: 'http://127.0.0.1:1337',
|
||||
authorId: user1.id
|
||||
})
|
||||
testApp1Id = testApp1.id
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче