forked from wangziqi/gongxue-base
132 lines
4.8 KiB
JavaScript
132 lines
4.8 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
|
|
process.env.NODE_ENV = 'development';
|
|
const { findUserBySessionToken, findUserByVerifiedSupabasePayload } = await import('../apps/api/src/core/auth-context.ts');
|
|
|
|
const AUTH_USER_ID = '11111111-1111-4111-8111-111111111111';
|
|
const TENANT_ID = '22222222-2222-4222-8222-222222222222';
|
|
const OTHER_TENANT_ID = '33333333-3333-4333-8333-333333333333';
|
|
const platformSession = {
|
|
id: '44444444-4444-4444-8444-444444444444',
|
|
username: 'platform-admin',
|
|
phone: null,
|
|
name: 'Platform Admin',
|
|
avatarUrl: null,
|
|
primaryRole: 'platform_admin',
|
|
createdAt: new Date(0).toISOString(),
|
|
tenantId: null,
|
|
sessionId: AUTH_USER_ID,
|
|
sessionExpiresAt: new Date(Date.now() + 60_000).toISOString(),
|
|
authSource: 'supabase_jwt',
|
|
authUserId: AUTH_USER_ID,
|
|
platformPermissions: { '*': true },
|
|
};
|
|
|
|
{
|
|
const calls = [];
|
|
const tenantSession = { ...platformSession, primaryRole: 'student', tenantId: TENANT_ID, authSource: 'app_session' };
|
|
const session = await findUserBySessionToken('tk_test_session', async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return tenantSession;
|
|
});
|
|
assert.equal(session, tenantSession);
|
|
assert.match(calls[0].sql, /join public\.tenants t on t\.id = s\.tenant_id/);
|
|
assert.match(calls[0].sql, /t\.status = 'active'/);
|
|
assert.match(calls[0].sql, /tm\.status = 'active'/);
|
|
assert.match(calls[0].sql, /u\.status = 'active'/);
|
|
}
|
|
|
|
{
|
|
const calls = [];
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'authenticated',
|
|
app_metadata: { provider: 'phone' },
|
|
}, '', async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return platformSession;
|
|
});
|
|
assert.equal(session, platformSession, 'standard Supabase role=authenticated must not downgrade a database platform admin');
|
|
assert.equal(calls.length, 1);
|
|
assert.equal(calls[0].sql.includes('tenant_memberships'), false, 'global platform lookup must not require tenant membership');
|
|
}
|
|
|
|
{
|
|
const calls = [];
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'authenticated',
|
|
}, OTHER_TENANT_ID, async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return platformSession;
|
|
});
|
|
assert.equal(session?.primaryRole, 'platform_admin');
|
|
assert.equal(session?.tenantId, null, 'global platform identity must not acquire tenant membership from request context');
|
|
assert.equal(calls.length, 1, 'platform admin should resolve before tenant membership lookup');
|
|
}
|
|
|
|
{
|
|
const calls = [];
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'service_role',
|
|
app_role: 'platform_admin',
|
|
app_metadata: { app_role: 'platform_admin' },
|
|
}, '', async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return null;
|
|
});
|
|
assert.equal(session, null, 'JWT role claims alone must never create platform authority');
|
|
assert.equal(calls.length, 1, 'JWT-only elevation must stop after authoritative platform lookup fails');
|
|
}
|
|
|
|
{
|
|
const calls = [];
|
|
const studentSession = { ...platformSession, primaryRole: 'student', tenantId: TENANT_ID, platformPermissions: {} };
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'authenticated',
|
|
app_metadata: { app_role: 'platform_admin' },
|
|
}, TENANT_ID, async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return calls.length === 1 ? null : studentSession;
|
|
});
|
|
assert.equal(session?.primaryRole, 'student', 'a malicious app_role claim must not elevate a tenant member');
|
|
assert.equal(calls.length, 2);
|
|
assert.match(calls[1].sql, /join public\.tenants t on t\.id = tm\.tenant_id/);
|
|
assert.match(calls[1].sql, /t\.status = 'active'/);
|
|
assert.match(calls[1].sql, /tm\.status = 'active'/);
|
|
assert.match(calls[1].sql, /u\.status = 'active'/);
|
|
}
|
|
|
|
{
|
|
const calls = [];
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'authenticated',
|
|
app_metadata: { tenant_id: TENANT_ID },
|
|
}, OTHER_TENANT_ID, async (sql, params) => {
|
|
calls.push({ sql, params });
|
|
return platformSession;
|
|
});
|
|
assert.equal(session?.primaryRole, 'platform_admin', 'database platform admin may select a tenant beyond its JWT default claim');
|
|
assert.equal(session?.tenantId, null, 'JWT tenant defaults must not become implicit platform membership');
|
|
assert.equal(calls.length, 1);
|
|
}
|
|
|
|
{
|
|
let queryCount = 0;
|
|
const session = await findUserByVerifiedSupabasePayload({
|
|
sub: AUTH_USER_ID,
|
|
role: 'authenticated',
|
|
app_metadata: { tenant_id: TENANT_ID },
|
|
}, OTHER_TENANT_ID, async () => {
|
|
queryCount += 1;
|
|
return null;
|
|
});
|
|
assert.equal(session, null, 'signed tenant claim must not be overwritten by request context');
|
|
assert.equal(queryCount, 1, 'tenant mismatch may perform only the authoritative global platform lookup');
|
|
}
|
|
|
|
console.log('[PASS] Supabase JWT platform authority contract');
|