29 lines
2.3 KiB
TypeScript
29 lines
2.3 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import {SignJWT} from 'jose'
|
|
const database=process.env.MMAPP_OWN_SQL_DB
|
|
if(!database)console.log('server secrets SQL: skipped; explicit owned database required')
|
|
else{
|
|
assert(/^mm_accept_166_\d+$/.test(database));assert.equal(new URL(process.env.DATABASE_URL!).pathname,'/'+database)
|
|
process.env.AUTH_REQUIRED='true';process.env.AUTH_JWT_SECRET='owned196-server-read-secret';process.env.AUTH_ISSUER='https://owned196.test';process.env.NODE_ENV='test'
|
|
const {pool,closePool}=await import('../db/index.js');const {initDatabase}=await import('../db/bootstrap.js');const {buildApp}=await import('../index.js')
|
|
assert.equal((await pool.query('SELECT current_database() AS name')).rows[0].name,database)
|
|
let serverId:number|undefined;const app=await buildApp({logger:false,startScheduler:false})
|
|
try{
|
|
await initDatabase()
|
|
serverId=Number((await pool.query("INSERT INTO servers(name,host,enabled,username,password) VALUES('own196-secret','192.0.2.196',false,'fixture','own196-password') RETURNING id")).rows[0].id)
|
|
for(const permission of ['mm:servers:read','mm:servers:write','mm:servers:admin']){
|
|
const token=await new SignJWT({sub:'own196',apps:['mm'],permissions:[permission]}).setProtectedHeader({alg:'HS256'}).setIssuer('https://owned196.test').setExpirationTime('1h').sign(new TextEncoder().encode('owned196-server-read-secret'))
|
|
for(const url of ['/api/servers','/api/servers/'+serverId]){
|
|
const r=await app.inject({method:'GET',url,headers:{authorization:'Bearer '+token}});assert.equal(r.statusCode,200)
|
|
const body=r.json(),row=Array.isArray(body)?body.find(s=>s.id===serverId):body
|
|
assert.equal(row.password,permission.endsWith(':read')?'':'own196-password');assert.equal(row.username,'fixture')
|
|
}
|
|
}
|
|
assert.equal((await pool.query('SELECT password FROM servers WHERE id=$1',[serverId])).rows[0].password,'own196-password','projection never changes stored credentials')
|
|
const noToken=await app.inject({method:'GET',url:'/api/servers'});assert.equal(noToken.statusCode,401)
|
|
console.log('server secrets owned SQL: reader/writer/admin list/detail and unchanged stored password passed')
|
|
}finally{
|
|
await app.close();if(serverId!==undefined)await pool.query('DELETE FROM servers WHERE id=$1',[serverId]);await closePool()
|
|
}
|
|
}
|