diff --git a/functions/src/migration.test.ts b/functions/src/migration.test.ts index a0e6b890..cef7f958 100644 --- a/functions/src/migration.test.ts +++ b/functions/src/migration.test.ts @@ -82,11 +82,16 @@ describe('migration API', () => { }); it('returns small collections whole, with ids', async () => { - expect((await get('/api/migration/spaces/s1/tokens')).body).toEqual([{ id: 'TOKEN000000000000001', name: 'web', createdAt: '2025-01-02T00:00:00.000Z' }]); expect((await get('/api/migration/spaces/s1/schemas')).body).toEqual([{ id: 'page', type: 'ROOT', fields: [] }]); expect((await get('/api/migration/spaces/s1/webhooks')).body).toEqual([]); }); + it('does not expose space API tokens', async () => { + const res = await get('/api/migration/spaces/s1/tokens'); + expect(res.status).toBe(404); + expect(res.text).not.toContain('TOKEN000000000000001'); + }); + it('pages large collections by 500, cursor = last id, null at the end', async () => { const first = (await get('/api/migration/spaces/s1/translations')).body; expect(first.items).toHaveLength(500); diff --git a/functions/src/migration.ts b/functions/src/migration.ts index 7271be62..9ec896b0 100644 --- a/functions/src/migration.ts +++ b/functions/src/migration.ts @@ -81,7 +81,9 @@ MIGRATION.get('/api/migration/spaces/:spaceId', async (req, res) => { res.json(toJson({ id: doc.id, data: () => doc.data() })); }); -for (const name of ['tokens', 'webhooks', 'schemas']) { +// Space API tokens are deliberately absent: the self-hosted import does not carry them over, and +// they are credentials, so the migration token should not be able to read them. +for (const name of ['webhooks', 'schemas']) { MIGRATION.get(`/api/migration/spaces/:spaceId/${name}`, async (req, res) => { if (!(await requireSpace(req, res))) return; const snapshot = await firestoreService.collection(`spaces/${req.params['spaceId']}/${name}`).orderBy('__name__').get();