bend_puzzle/server/auth.js
2026-07-31 12:54:46 +09:00

20 lines
1.1 KiB
JavaScript

'use strict';
function createAuthenticator(options){
const {playerPattern,tokenPattern,readPlayer,hashToken,safeEqual}=options||{};
if(!(playerPattern instanceof RegExp)||!(tokenPattern instanceof RegExp))throw new TypeError('Authentication patterns are required');
if(typeof readPlayer!=='function'||typeof hashToken!=='function'||typeof safeEqual!=='function')throw new TypeError('Authentication ports are required');
const parse=req=>{
const raw=String(req?.headers?.authorization||''),match=/^Bearer\s+([^.]*)\.([^.]*)$/i.exec(raw);
if(!match||!playerPattern.test(match[1])||!tokenPattern.test(match[2]))throw Object.assign(new Error('Unauthorized'),{status:401});
return{playerId:match[1].toLowerCase(),token:match[2].toLowerCase()};
};
const player=async req=>{
const auth=parse(req),record=await readPlayer(auth.playerId);
if(!safeEqual(record.tokenHash,hashToken(auth.token)))throw Object.assign(new Error('Invalid cloud sync code'),{status:403});
return{...auth,record};
};
return Object.freeze({parse,player});
}
module.exports=Object.freeze({createAuthenticator});