This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
Tom Moor 1b6a986986
chore: Refactor authentication pass between subdomains (#1619)
* fix: Use get request instead of cookie to transfer token between domains

* Add domain to database
Add redirects to team domain when present

* 30s -> 1m

* fix: Avoid redirect loop if subdomain and domain set

* fix: Create a transfer specific token to prevent replay requests

* refactor: Move isCustomDomain out of shared as it won't work on the client
2020-11-04 19:54:04 -08:00

80 lines
2.1 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): Promise<User> {
const payload = getJWTPayload(token);
// check the token is within it's expiration time
if (payload.expiresAt) {
if (new Date(payload.expiresAt) < new Date()) {
throw new AuthenticationError("Expired token");
}
}
const user = await User.findByPk(payload.id);
if (payload.type === "transfer") {
// If the user has made a single API request since the transfer token was
// created then it's no longer valid, they'll need to sign in again.
if (user.lastActiveAt > new Date(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;
}
export async function getUserForEmailSigninToken(token: string): Promise<User> {
const payload = getJWTPayload(token);
if (payload.type !== "email-signin") {
throw new AuthenticationError("Invalid 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;
}