demos for spacedust

explicit cors

+32 -49
+32 -49
server/index.js
··· 20 20 // (this is only used when there are no subscribers registered) 21 21 const DUMMY_DID = 'did:plc:zzzzzzzzzzzzzzzzzzzzzzzz'; 22 22 23 - const CORS_PERMISSIVE = req => ({ 24 - 'Access-Control-Allow-Origin': req.headers.origin, // DANGERRRRR 25 - 'Access-Control-Allow-Methods': 'OPTIONS, GET, POST', 26 - 'Access-Control-Allow-Headers': 'Content-Type', 27 - 'Access-Control-Allow-Credentials': 'true', // TODO: *def* want to restrict allowed origin, probably 28 - }); 29 - 30 23 let spacedust; 31 24 let spacedustEverStarted = false; 32 25 ··· 341 334 res.end(JSON.stringify({ sup: 'bye' })); 342 335 } 343 336 344 - const handleOpenSesame = async (db, req, res, appSecret) => { 337 + const handleTopSecret = async (db, req, res, appSecret) => { 345 338 let info = getAccountCookie(req, res, appSecret, null, true); 346 339 if (!info) return res.writeHead(400).end(JSON.stringify({ reason: 'failed to verify cookie signature' })); 347 340 const [did, _session, _isAdmin] = info; ··· 364 357 } 365 358 }; 366 359 367 - const requestListener = (secrets, jwks, whoamiHost, db, adminDid) => attempt((req, res) => { 360 + const withCors = (allowedOrigin, listener) => { 361 + const corsHeaders = new Headers({ 362 + 'Access-Control-Allow-Origin': allowedOrigin, 363 + 'Access-Control-Allow-Methods': 'OPTIONS, GET, POST', 364 + 'Access-Control-Allow-Headers': 'Content-Type', 365 + 'Access-Control-Allow-Credentials': 'true', 366 + }); 367 + return (req, res) => { 368 + res.setHeaders(corsHeaders); 369 + if (req.method === 'OPTIONS') { 370 + return res.writeHead(204).end(); 371 + } 372 + return listener(req, res); 373 + } 374 + } 375 + 376 + const requestListener = 377 + (secrets, jwks, allowedOrigin, whoamiHost, db, adminDid) => 378 + attempt(withCors(allowedOrigin, (req, res) => { 379 + 368 380 if (req.method === 'GET' && req.url === '/') { 369 381 return handleIndex(req, res, { PUBKEY: secrets.pushKeys.publicKey }); 370 382 } 371 - if (req.method === 'GET' && req.url === '/service-worker.js') { 372 - return handleServiceWorker(req, res, { PUBKEY: secrets.pushKeys.publicKey }); 373 - } 374 - 375 - if (req.method === 'OPTIONS' && req.url === '/hello') { 376 - return res.writeHead(204, CORS_PERMISSIVE(req)).end(); 377 - } 378 383 if (req.method === 'GET' && req.url === '/hello') { 379 - res.setHeaders(new Headers(CORS_PERMISSIVE(req))); 380 384 return handleHello(db, req, res, secrets, whoamiHost, adminDid); 381 385 } 382 - 383 - if (req.method === 'OPTIONS' && req.url === '/verify') { 384 - // TODO: probably restrict the origin 385 - return res.writeHead(204, CORS_PERMISSIVE(req)).end(); 386 - } 387 386 if (req.method === 'POST' && req.url === '/verify') { 388 - res.setHeaders(new Headers(CORS_PERMISSIVE(req))); 389 387 return handleVerify(db, req, res, secrets, whoamiHost, adminDid, jwks); 390 388 } 391 - 392 - if (req.method === 'OPTIONS' && req.url === '/subscribe') { 393 - // TODO: probably restrict the origin 394 - return res.writeHead(204, CORS_PERMISSIVE(req)).end(); 395 - } 396 389 if (req.method === 'POST' && req.url === '/subscribe') { 397 - res.setHeaders(new Headers(CORS_PERMISSIVE(req))); 398 390 return handleSubscribe(db, req, res, secrets.appSecret, adminDid); 399 391 } 400 - 401 - if (req.method === 'OPTIONS' && req.url === '/logout') { 402 - // TODO: probably restrict the origin 403 - return res.writeHead(204, CORS_PERMISSIVE(req)).end(); 404 - } 405 392 if (req.method === 'POST' && req.url === '/logout') { 406 - res.setHeaders(new Headers(CORS_PERMISSIVE(req))); 407 393 return handleLogout(db, req, res, secrets.appSecret); 408 394 } 409 - 410 - if (req.method === 'OPTIONS' && req.url === '/super-top-secret-access') { 411 - // TODO: probably restrict the origin 412 - return res.writeHead(204, CORS_PERMISSIVE(req)).end(); 413 - } 414 395 if (req.method === 'POST' && req.url === '/super-top-secret-access') { 415 - res.setHeaders(new Headers(CORS_PERMISSIVE(req))); 416 - return handleOpenSesame(db, req, res, secrets.appSecret); 396 + return handleTopSecret(db, req, res, secrets.appSecret); 417 397 } 418 398 419 - res 420 - .setHeaders(new Headers(CORS_PERMISSIVE(req))) 421 - .writeHead(404) 422 - .end('not found (sorry)'); 423 - }); 399 + res.writeHead(404).end('not found (sorry)'); 400 + })); 424 401 425 402 const main = env => { 426 403 if (!env.ADMIN_DID) throw new Error('ADMIN_DID is required to run'); ··· 448 425 const host = env.HOST ?? 'localhost'; 449 426 const port = parseInt(env.PORT ?? 8000, 10); 450 427 428 + const allowedOrigin = env.ALLOWED_ORIGIN ?? 'http://127.0.0.1:5173'; 429 + 451 430 http 452 - .createServer(requestListener(secrets, jwks, whoamiHost, db, adminDid)) 453 - .listen(port, host, () => console.log(`listening at http://${host}:${port}`)); 431 + .createServer(requestListener(secrets, jwks, allowedOrigin, whoamiHost, db, adminDid)) 432 + .listen( 433 + port, 434 + host, 435 + () => console.log(`listening at http://${host}:${port} with allowed origin: ${allowedOrigin}`), 436 + ); 454 437 }; 455 438 456 439 main(process.env);