feat(mam-api): auth router skeleton + setup-required endpoint
This commit is contained in:
parent
cb7cc9a43e
commit
49a9543942
3 changed files with 62 additions and 0 deletions
|
|
@ -11,6 +11,7 @@ import { errorHandler } from './middleware/errors.js';
|
|||
import { requireAuth } from './middleware/auth.js';
|
||||
import { loadS3ConfigFromDb } from './s3/client.js';
|
||||
|
||||
import authRouter from './routes/auth.js';
|
||||
// Routes
|
||||
import assetsRouter from './routes/assets.js';
|
||||
import projectsRouter from './routes/projects.js';
|
||||
|
|
@ -104,6 +105,7 @@ app.use('/api/v1', (req, res, next) => {
|
|||
});
|
||||
|
||||
// ── API Routes ────────────────────────────────────────────────────────────────
|
||||
app.use('/api/v1/auth', authRouter);
|
||||
app.use('/api/v1/assets', assetsRouter);
|
||||
app.use('/api/v1/projects', projectsRouter);
|
||||
app.use('/api/v1/bins', binsRouter);
|
||||
|
|
|
|||
23
services/mam-api/src/routes/auth.js
Normal file
23
services/mam-api/src/routes/auth.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import express from 'express';
|
||||
import pool from '../db/pool.js';
|
||||
import { DEV_USER_ID } from '../middleware/auth.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Real users = anyone except the seeded dev row.
|
||||
async function realUserCount() {
|
||||
const { rows } = await pool.query(
|
||||
`SELECT COUNT(*)::int AS n FROM users WHERE id <> $1`, [DEV_USER_ID]);
|
||||
return rows[0].n;
|
||||
}
|
||||
|
||||
// GET /api/v1/auth/setup-required
|
||||
// Cheap, no auth. Used by AuthGate to decide between Login and Setup screens.
|
||||
router.get('/setup-required', async (_req, res, next) => {
|
||||
try {
|
||||
res.json({ required: (await realUserCount()) === 0 });
|
||||
} catch (err) { next(err); }
|
||||
});
|
||||
|
||||
export default router;
|
||||
export { realUserCount };
|
||||
37
services/mam-api/test/routes/auth.test.js
Normal file
37
services/mam-api/test/routes/auth.test.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { isTestDbConfigured, setupTestDb } from '../helpers/setup-db.js';
|
||||
import express from 'express';
|
||||
import authRouter from '../../src/routes/auth.js';
|
||||
|
||||
async function appWithAuth(pool) {
|
||||
process.env.DATABASE_URL = process.env.TEST_DATABASE_URL;
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use('/api/v1/auth', authRouter);
|
||||
return new Promise(r => {
|
||||
const srv = app.listen(0, '127.0.0.1', () => {
|
||||
r({ baseUrl: 'http://127.0.0.1:' + srv.address().port, close: () => new Promise(rs => srv.close(rs)) });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test('GET /auth/setup-required returns { required: true } on empty users (modulo dev seed)', { skip: !isTestDbConfigured() && 'TEST_DATABASE_URL not set' }, async () => {
|
||||
const pool = await setupTestDb();
|
||||
const { baseUrl, close } = await appWithAuth(pool);
|
||||
try {
|
||||
const res = await fetch(baseUrl + '/api/v1/auth/setup-required');
|
||||
assert.equal(res.status, 200);
|
||||
assert.deepEqual(await res.json(), { required: true });
|
||||
} finally { await close(); await pool.end(); }
|
||||
});
|
||||
|
||||
test('GET /auth/setup-required returns { required: false } once a real user exists', { skip: !isTestDbConfigured() && 'TEST_DATABASE_URL not set' }, async () => {
|
||||
const pool = await setupTestDb();
|
||||
await pool.query(`INSERT INTO users (username, password_hash) VALUES ('admin', 'x')`);
|
||||
const { baseUrl, close } = await appWithAuth(pool);
|
||||
try {
|
||||
const res = await fetch(baseUrl + '/api/v1/auth/setup-required');
|
||||
assert.deepEqual(await res.json(), { required: false });
|
||||
} finally { await close(); await pool.end(); }
|
||||
});
|
||||
Loading…
Reference in a new issue