bde148f286
* 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
318 lines
11 KiB
TypeScript
318 lines
11 KiB
TypeScript
import { Router } from 'express'
|
|
import cors from 'cors'
|
|
|
|
import { validateScopes, authorizeResolver } from '@/modules/shared'
|
|
|
|
import { makeOgImage } from '@/modules/previews/ogImage'
|
|
|
|
import { db } from '@/db/knex'
|
|
import {
|
|
getObjectPreviewBufferOrFilepathFactory,
|
|
sendObjectPreviewFactory,
|
|
checkStreamPermissionsFactory
|
|
} from '@/modules/previews/services/management'
|
|
import {
|
|
getObjectPreviewInfoFactory,
|
|
getPreviewImageFactory,
|
|
storeObjectPreviewFactory
|
|
} from '@/modules/previews/repository/previews'
|
|
import {
|
|
getCommitFactory,
|
|
getPaginatedBranchCommitsItemsFactory,
|
|
legacyGetPaginatedStreamCommitsPageFactory
|
|
} from '@/modules/core/repositories/commits'
|
|
import {
|
|
getStreamCollaboratorsFactory,
|
|
getStreamFactory
|
|
} from '@/modules/core/repositories/streams'
|
|
import { getPaginatedBranchCommitsItemsByNameFactory } from '@/modules/core/services/commit/retrieval'
|
|
import { getStreamBranchByNameFactory } from '@/modules/core/repositories/branches'
|
|
import { getFormattedObjectFactory } from '@/modules/core/repositories/objects'
|
|
import { getProjectDbClient } from '@/modules/multiregion/utils/dbSelector'
|
|
import { createObjectPreviewFactory } from '@/modules/previews/services/createObjectPreview'
|
|
import { createAppTokenFactory } from '@/modules/core/services/tokens'
|
|
import {
|
|
storeApiTokenFactory,
|
|
storeTokenResourceAccessDefinitionsFactory,
|
|
storeTokenScopesFactory,
|
|
storeUserServerAppTokenFactory
|
|
} from '@/modules/core/repositories/tokens'
|
|
import {
|
|
getPrivateObjectsServerOrigin,
|
|
getServerOrigin,
|
|
previewServiceShouldUsePrivateObjectsServerUrl
|
|
} from '@/modules/shared/helpers/envHelper'
|
|
import { requestObjectPreviewFactory } from '@/modules/previews/queues/previews'
|
|
import type { Queue } from 'bull'
|
|
import type { Knex } from 'knex'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const httpErrorImage = (httpErrorCode: number) =>
|
|
fileURLToPath(
|
|
import.meta.resolve(`#/assets/previews/images/preview_${httpErrorCode}.png`)
|
|
)
|
|
|
|
const noPreviewImage = () =>
|
|
fileURLToPath(import.meta.resolve('#/assets/previews/images/no_preview.png'))
|
|
|
|
const buildCreateObjectPreviewFunction = ({
|
|
projectDb,
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}: {
|
|
projectDb: Knex
|
|
previewRequestQueue: Queue
|
|
responseQueueName: string
|
|
}) => {
|
|
return createObjectPreviewFactory({
|
|
requestObjectPreview: requestObjectPreviewFactory({
|
|
queue: previewRequestQueue,
|
|
responseQueue: responseQueueName
|
|
}),
|
|
// use the private server origin if defined, otherwise use the public server origin
|
|
serverOrigin: previewServiceShouldUsePrivateObjectsServerUrl()
|
|
? getPrivateObjectsServerOrigin()
|
|
: getServerOrigin(),
|
|
storeObjectPreview: storeObjectPreviewFactory({ db: projectDb }),
|
|
getStreamCollaborators: getStreamCollaboratorsFactory({ db }),
|
|
createAppToken: createAppTokenFactory({
|
|
storeApiToken: storeApiTokenFactory({ db }),
|
|
storeTokenScopes: storeTokenScopesFactory({ db }),
|
|
storeTokenResourceAccessDefinitions: storeTokenResourceAccessDefinitionsFactory({
|
|
db
|
|
}),
|
|
storeUserServerAppToken: storeUserServerAppTokenFactory({ db })
|
|
})
|
|
})
|
|
}
|
|
|
|
export const previewRouterFactory = ({
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}: {
|
|
previewRequestQueue: Queue
|
|
responseQueueName: string
|
|
}): Router => {
|
|
const app = Router()
|
|
|
|
app.options('/preview/:streamId/:angle?', cors())
|
|
app.get('/preview/:streamId/:angle?', cors(), async (req, res) => {
|
|
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
|
|
const checkStreamPermissions = checkStreamPermissionsFactory({
|
|
validateScopes,
|
|
authorizeResolver,
|
|
// getting the stream from the main DB, cause it needs to join on roles
|
|
getStream: getStreamFactory({ db })
|
|
})
|
|
const { hasPermissions, httpErrorCode } = await checkStreamPermissions(req)
|
|
if (!hasPermissions) {
|
|
// return res.status( httpErrorCode ).end()
|
|
return res.sendFile(await httpErrorImage(httpErrorCode))
|
|
}
|
|
|
|
const getCommitsByStreamId = legacyGetPaginatedStreamCommitsPageFactory({
|
|
db: projectDb
|
|
})
|
|
|
|
const { commits } = await getCommitsByStreamId({
|
|
streamId: req.params.streamId,
|
|
limit: 1,
|
|
ignoreGlobalsBranch: true,
|
|
cursor: undefined
|
|
})
|
|
if (!commits || commits.length === 0) {
|
|
return res.sendFile(await noPreviewImage())
|
|
}
|
|
const lastCommit = commits[0]
|
|
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
|
logger: req.log,
|
|
getObject: getFormattedObjectFactory({ db: projectDb }),
|
|
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db: projectDb }),
|
|
createObjectPreview: buildCreateObjectPreviewFunction({
|
|
projectDb,
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}),
|
|
getPreviewImage: getPreviewImageFactory({ db: projectDb })
|
|
})
|
|
|
|
const sendObjectPreview = sendObjectPreviewFactory({
|
|
// getting the stream from the projectDb here, to handle preview data properly
|
|
getStream: getStreamFactory({ db: projectDb }),
|
|
getObjectPreviewBufferOrFilepath,
|
|
makeOgImage
|
|
})
|
|
|
|
return sendObjectPreview(
|
|
req,
|
|
res,
|
|
req.params.streamId,
|
|
lastCommit.referencedObject,
|
|
req.params.angle
|
|
)
|
|
})
|
|
|
|
app.options('/preview/:streamId/branches/:branchName/:angle?', cors())
|
|
app.get(
|
|
'/preview/:streamId/branches/:branchName/:angle?',
|
|
cors(),
|
|
async (req, res) => {
|
|
const checkStreamPermissions = checkStreamPermissionsFactory({
|
|
validateScopes,
|
|
authorizeResolver,
|
|
// getting the stream from the main DB, cause it needs to join on roles
|
|
getStream: getStreamFactory({ db })
|
|
})
|
|
const { hasPermissions, httpErrorCode } = await checkStreamPermissions(req)
|
|
if (!hasPermissions) {
|
|
// return res.status( httpErrorCode ).end()
|
|
return res.sendFile(await httpErrorImage(httpErrorCode))
|
|
}
|
|
|
|
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
|
|
|
|
let commitsObj
|
|
try {
|
|
const getCommitsByBranchName = getPaginatedBranchCommitsItemsByNameFactory({
|
|
getStreamBranchByName: getStreamBranchByNameFactory({ db: projectDb }),
|
|
getPaginatedBranchCommitsItems: getPaginatedBranchCommitsItemsFactory({
|
|
db: projectDb
|
|
})
|
|
})
|
|
commitsObj = await getCommitsByBranchName({
|
|
streamId: req.params.streamId,
|
|
branchName: req.params.branchName,
|
|
limit: 1,
|
|
cursor: undefined
|
|
})
|
|
} catch {
|
|
commitsObj = {}
|
|
}
|
|
const { commits } = commitsObj
|
|
if (!commits || commits.length === 0) {
|
|
return res.sendFile(await noPreviewImage())
|
|
}
|
|
const lastCommit = commits[0]
|
|
|
|
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
|
logger: req.log,
|
|
getObject: getFormattedObjectFactory({ db: projectDb }),
|
|
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db: projectDb }),
|
|
createObjectPreview: buildCreateObjectPreviewFunction({
|
|
projectDb,
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}),
|
|
getPreviewImage: getPreviewImageFactory({ db: projectDb })
|
|
})
|
|
|
|
const sendObjectPreview = sendObjectPreviewFactory({
|
|
// getting the stream from the projectDb here, to handle preview data properly
|
|
getStream: getStreamFactory({ db: projectDb }),
|
|
getObjectPreviewBufferOrFilepath,
|
|
makeOgImage
|
|
})
|
|
|
|
return sendObjectPreview(
|
|
req,
|
|
res,
|
|
req.params.streamId,
|
|
lastCommit.referencedObject,
|
|
req.params.angle
|
|
)
|
|
}
|
|
)
|
|
|
|
app.options('/preview/:streamId/commits/:commitId/:angle?', cors())
|
|
app.get('/preview/:streamId/commits/:commitId/:angle?', cors(), async (req, res) => {
|
|
const checkStreamPermissions = checkStreamPermissionsFactory({
|
|
validateScopes,
|
|
authorizeResolver,
|
|
// getting the stream from the main DB, cause it needs to join on roles
|
|
getStream: getStreamFactory({ db })
|
|
})
|
|
const { hasPermissions, httpErrorCode } = await checkStreamPermissions(req)
|
|
if (!hasPermissions) {
|
|
// return res.status( httpErrorCode ).end()
|
|
return res.sendFile(await httpErrorImage(httpErrorCode))
|
|
}
|
|
|
|
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
|
|
|
|
const getCommit = getCommitFactory({ db: projectDb })
|
|
const commit = await getCommit(req.params.commitId, {
|
|
streamId: req.params.streamId
|
|
})
|
|
if (!commit) return res.sendFile(await noPreviewImage())
|
|
|
|
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
|
logger: req.log,
|
|
getObject: getFormattedObjectFactory({ db: projectDb }),
|
|
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db: projectDb }),
|
|
createObjectPreview: buildCreateObjectPreviewFunction({
|
|
projectDb,
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}),
|
|
getPreviewImage: getPreviewImageFactory({ db: projectDb })
|
|
})
|
|
|
|
const sendObjectPreview = sendObjectPreviewFactory({
|
|
// getting the stream from the projectDb here, to handle preview data properly
|
|
getStream: getStreamFactory({ db: projectDb }),
|
|
getObjectPreviewBufferOrFilepath,
|
|
makeOgImage
|
|
})
|
|
return sendObjectPreview(
|
|
req,
|
|
res,
|
|
req.params.streamId,
|
|
commit.referencedObject,
|
|
req.params.angle
|
|
)
|
|
})
|
|
|
|
app.options('/preview/:streamId/objects/:objectId/:angle?', cors())
|
|
app.get('/preview/:streamId/objects/:objectId/:angle?', cors(), async (req, res) => {
|
|
const checkStreamPermissions = checkStreamPermissionsFactory({
|
|
validateScopes,
|
|
authorizeResolver,
|
|
// getting the stream from the main DB, cause it needs to join on roles
|
|
getStream: getStreamFactory({ db })
|
|
})
|
|
const { hasPermissions } = await checkStreamPermissions(req)
|
|
if (!hasPermissions) {
|
|
return res.status(403).end()
|
|
}
|
|
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
|
|
|
|
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
|
logger: req.log,
|
|
getObject: getFormattedObjectFactory({ db: projectDb }),
|
|
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db: projectDb }),
|
|
createObjectPreview: buildCreateObjectPreviewFunction({
|
|
projectDb,
|
|
previewRequestQueue,
|
|
responseQueueName
|
|
}),
|
|
getPreviewImage: getPreviewImageFactory({ db: projectDb })
|
|
})
|
|
|
|
const sendObjectPreview = sendObjectPreviewFactory({
|
|
// getting the stream from the projectDb here, to handle preview data properly
|
|
getStream: getStreamFactory({ db: projectDb }),
|
|
getObjectPreviewBufferOrFilepath,
|
|
makeOgImage
|
|
})
|
|
|
|
return sendObjectPreview(
|
|
req,
|
|
res,
|
|
req.params.streamId,
|
|
req.params.objectId,
|
|
req.params.angle
|
|
)
|
|
})
|
|
return app
|
|
}
|