Gate admin menu and authoring with shared JWT
This commit is contained in:
@@ -33,29 +33,31 @@ function documentKind(type: SourceFileType) {
|
||||
return type === 'web_capture' ? 'WEB CAPTURE' : type.toUpperCase()
|
||||
}
|
||||
|
||||
async function uploadAsset(baseUrl: string, levelId: string, manifestDir: string, document: MysteryDocument) {
|
||||
async function uploadAsset(baseUrl: string, levelId: string, manifestDir: string, document: MysteryDocument, authorization?: string) {
|
||||
if (!document.asset) return undefined
|
||||
const assetPath = path.resolve(manifestDir, document.asset)
|
||||
const form = new FormData()
|
||||
form.append('file', new Blob([await readFile(assetPath)]), path.basename(assetPath))
|
||||
const response = await requireOk(await fetch(`${baseUrl}/api/levels/${levelId}/documents?edit=1`, { method: 'POST', body: form }), `Upload ${document.asset}`)
|
||||
const response = await requireOk(await fetch(`${baseUrl}/api/levels/${levelId}/documents?edit=1`, { method: 'POST', headers: authorization ? { authorization } : undefined, body: form }), `Upload ${document.asset}`)
|
||||
return await response.json() as CaseDocument
|
||||
}
|
||||
|
||||
export async function importMysteryTemplate(manifestPath: string, baseUrl = 'http://localhost:8787') {
|
||||
export async function importMysteryTemplate(manifestPath: string, baseUrl = 'http://localhost:8787', adminJwt = process.env.OSINT_ADMIN_JWT) {
|
||||
const absoluteManifest = path.resolve(manifestPath)
|
||||
const manifest = JSON.parse(await readFile(absoluteManifest, 'utf8')) as MysteryManifest
|
||||
const manifestDir = path.dirname(absoluteManifest)
|
||||
const authoringId = `${manifest.slug}-authoring-${Date.now()}`
|
||||
const authorization = adminJwt ? `Bearer ${adminJwt}` : undefined
|
||||
const headers = { 'content-type': 'application/json', ...(authorization ? { authorization } : {}) }
|
||||
const createdResponse = await requireOk(await fetch(`${baseUrl}/api/levels`, {
|
||||
method: 'POST', headers: { 'content-type': 'application/json' },
|
||||
method: 'POST', headers,
|
||||
body: JSON.stringify({ id: authoringId, title: manifest.title, subtitle: manifest.subtitle }),
|
||||
}), 'Create authoring level')
|
||||
const state = await createdResponse.json() as CaseState
|
||||
|
||||
const documents = new Map<string, CaseDocument>()
|
||||
for (const source of manifest.documents) {
|
||||
const uploaded = await uploadAsset(baseUrl, state.id, manifestDir, source)
|
||||
const uploaded = await uploadAsset(baseUrl, state.id, manifestDir, source, authorization)
|
||||
documents.set(source.key, {
|
||||
id: uploaded?.id || randomUUID(), title: source.title, kind: documentKind(source.fileType),
|
||||
date: source.publishedAt.slice(0, 10), publishedAt: source.publishedAt,
|
||||
@@ -87,15 +89,15 @@ export async function importMysteryTemplate(manifestPath: string, baseUrl = 'htt
|
||||
state.viewport = { x: 0, y: 28, zoom: 0.7 }
|
||||
|
||||
await requireOk(await fetch(`${baseUrl}/api/levels/${state.id}?edit=1`, {
|
||||
method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify(state),
|
||||
method: 'PUT', headers, body: JSON.stringify(state),
|
||||
}), 'Save authored mystery')
|
||||
const templateResponse = await requireOk(await fetch(`${baseUrl}/api/levels/${state.id}/templates?edit=1`, {
|
||||
method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ slug: manifest.slug, name: manifest.name }),
|
||||
method: 'POST', headers, body: JSON.stringify({ slug: manifest.slug, name: manifest.name }),
|
||||
}), 'Freeze mystery template')
|
||||
const template = await templateResponse.json() as { slug: string; currentVersion: number }
|
||||
const playableId = `${manifest.slug}-case-${Date.now()}`
|
||||
const playableResponse = await requireOk(await fetch(`${baseUrl}/api/templates/${manifest.slug}/levels?edit=1`, {
|
||||
method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id: playableId, title: manifest.title }),
|
||||
method: 'POST', headers, body: JSON.stringify({ id: playableId, title: manifest.title }),
|
||||
}), 'Instantiate playable mystery')
|
||||
const playable = await playableResponse.json() as CaseState
|
||||
return { manifest, template, authoringLevelId: state.id, playableLevel: playable }
|
||||
|
||||
Reference in New Issue
Block a user