fix: fixed bug with token generation and verification (#2427)

This commit is contained in:
Wyatt Johnson
2019-07-29 23:01:57 +00:00
committed by GitHub
parent c069bbe923
commit 8e130aa5d4
4 changed files with 58 additions and 26 deletions
@@ -128,9 +128,15 @@ export async function handleSuccessfulLogin(
const expiresIn = DateTime.fromJSDate(coral.now).plus({ days: 1 });
// Grab the token.
const token = await signTokenString(signingConfig, user, tenant, {
expiresIn: Math.floor(expiresIn.toSeconds()),
});
const token = await signTokenString(
signingConfig,
user,
tenant,
{
expiresIn: Math.round(expiresIn.toSeconds()),
},
coral.now
);
// Set the cache control headers.
res.header("Cache-Control", "private, no-cache, no-store, must-revalidate");
@@ -184,9 +190,15 @@ export async function handleOAuth2Callback(
const expiresIn = DateTime.fromJSDate(req.coral!.now).plus({ days: 1 });
// Grab the token.
const token = await signTokenString(signingConfig, user, tenant, {
expiresIn: Math.floor(expiresIn.toSeconds()),
});
const token = await signTokenString(
signingConfig,
user,
tenant,
{
expiresIn: Math.round(expiresIn.toSeconds()),
},
req.coral!.now
);
res.cookie(
COOKIE_NAME,
token,
@@ -30,12 +30,15 @@ export const JWTTokenSchema = Joi.object().keys({
sub: Joi.string().required(),
iat: Joi.number().required(),
iss: Joi.string().required(),
nbf: Joi.number(),
exp: Joi.number(),
pat: Joi.boolean(),
});
export function isJWTToken(token: JWTToken | object): token is JWTToken {
const { error } = Joi.validate(token, JWTTokenSchema);
const { error } = Joi.validate(token, JWTTokenSchema, {
allowUnknown: true,
});
return isNil(error);
}
+23 -11
View File
@@ -156,6 +156,10 @@ export interface JWTSigningConfig {
algorithm: JWTSigningAlgorithm;
}
export function dateToSeconds(date: Date): number {
return Math.round(DateTime.fromJSDate(date).toSeconds());
}
export function createAsymmetricSigningConfig(
algorithm: AsymmetricSigningAlgorithm,
secret: string
@@ -215,23 +219,31 @@ export const signTokenString = async (
{ algorithm, secret }: JWTSigningConfig,
user: Pick<User, "id">,
tenant: Pick<Tenant, "id">,
options: SigningTokenOptions = {}
options: SigningTokenOptions = {},
now = new Date()
) =>
jwt.sign({}, secret, {
jwtid: uuid(),
expiresIn: "1 day",
...options,
issuer: tenant.id,
subject: user.id,
algorithm,
});
jwt.sign(
{
iat: dateToSeconds(now),
},
secret,
{
jwtid: uuid(),
expiresIn: "1 day",
...options,
issuer: tenant.id,
subject: user.id,
algorithm,
}
);
export const signPATString = async (
{ algorithm, secret }: JWTSigningConfig,
user: User,
options: SigningTokenOptions
options: SigningTokenOptions,
now = new Date()
) =>
jwt.sign({ pat: true }, secret, {
jwt.sign({ pat: true, iat: dateToSeconds(now) }, secret, {
...options,
subject: user.id,
algorithm,
+13 -8
View File
@@ -275,16 +275,21 @@ export async function createToken(
const result = await createUserToken(mongo, tenant.id, user.id, name, now);
// Sign the token!
const signedToken = await signPATString(config, user, {
// Tokens are issued with the token ID as their JWT ID.
jwtid: result.token.id,
const signedToken = await signPATString(
config,
user,
{
// Tokens are issued with the token ID as their JWT ID.
jwtid: result.token.id,
// Tokens are issued with the tenant ID.
issuer: tenant.id,
// Tokens are issued with the tenant ID.
issuer: tenant.id,
// Tokens are not valid before the creation date.
notBefore: Math.round(DateTime.fromJSDate(now).toSeconds()),
});
// Tokens are not valid before the creation date.
notBefore: 0,
},
now
);
return { ...result, signedToken };
}