// @flow import add from "date-fns/add"; import sub from "date-fns/sub"; import { type Request } from "koa"; import { OAuthStateMismatchError } from "../errors"; import { getCookieDomain } from "./domains"; export class StateStore { key: string = "state"; store = (req: Request, callback: (err: ?Error, state?: string) => void) => { const state = Math.random().toString(36).substring(7); // $FlowFixMe req.cookies.set(this.key, state, { httpOnly: false, expires: add(new Date(), { minutes: 10 }), domain: getCookieDomain(req.hostname), }); callback(null, state); }; verify = ( req: Request, providedState: string, callback: (err: ?Error, ?boolean) => void ) => { // $FlowFixMe const state = req.cookies.get(this.key); if (!state) { return callback( new OAuthStateMismatchError("State not return in OAuth flow") ); } // $FlowFixMe req.cookies.set(this.key, "", { httpOnly: false, expires: sub(new Date(), { minutes: 1 }), domain: getCookieDomain(req.hostname), }); if (state !== providedState) { return callback(new OAuthStateMismatchError()); } callback(null, true); }; }