60 lines
1.4 KiB
JavaScript
60 lines
1.4 KiB
JavaScript
// @flow
|
|
import subMinutes from "date-fns/sub_minutes";
|
|
import JWT from "jsonwebtoken";
|
|
import { AuthenticationError } from "../errors";
|
|
import { User } from "../models";
|
|
|
|
function getJWTPayload(token) {
|
|
let payload;
|
|
try {
|
|
payload = JWT.decode(token);
|
|
} catch (err) {
|
|
throw new AuthenticationError("Unable to decode JWT token");
|
|
}
|
|
|
|
if (!payload) {
|
|
throw new AuthenticationError("Invalid token");
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
export async function getUserForJWT(token: string) {
|
|
const payload = getJWTPayload(token);
|
|
const user = await User.findByPk(payload.id);
|
|
|
|
try {
|
|
JWT.verify(token, user.jwtSecret);
|
|
} catch (err) {
|
|
throw new AuthenticationError("Invalid token");
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
export async function getUserForEmailSigninToken(token: string) {
|
|
const payload = getJWTPayload(token);
|
|
|
|
// check the token is within it's expiration time
|
|
if (payload.createdAt) {
|
|
if (new Date(payload.createdAt) < subMinutes(new Date(), 10)) {
|
|
throw new AuthenticationError("Expired token");
|
|
}
|
|
}
|
|
|
|
const user = await User.findByPk(payload.id);
|
|
|
|
// if user has signed in at all since the token was created then
|
|
// it's no longer valid, they'll need a new one.
|
|
if (user.lastSignedInAt > payload.createdAt) {
|
|
throw new AuthenticationError("Token has already been used");
|
|
}
|
|
|
|
try {
|
|
JWT.verify(token, user.jwtSecret);
|
|
} catch (err) {
|
|
throw new AuthenticationError("Invalid token");
|
|
}
|
|
|
|
return user;
|
|
}
|