saleor-app-sdk-REDIS_APL/src/verify-jwt.ts
Lukasz Ostrowski da351faae9
Add EXP field validation in JWT (#233)
* Add token exp validaiton

* revert lock
2023-04-26 14:09:50 +02:00

73 lines
2.1 KiB
TypeScript

import * as jose from "jose";
import { createDebug } from "./debug";
import { hasPermissionsInJwtToken } from "./has-permissions-in-jwt-token";
import { Permission } from "./types";
import { getJwksUrlFromSaleorApiUrl } from "./urls";
import { verifyTokenExpiration } from "./verify-token-expiration";
const debug = createDebug("verify-jwt");
export interface DashboardTokenPayload extends jose.JWTPayload {
app: string;
user_permissions: Permission[];
}
export interface verifyJWTArguments {
appId: string;
saleorApiUrl: string;
token: string;
requiredPermissions?: Permission[];
}
export const verifyJWT = async ({
saleorApiUrl,
token,
appId,
requiredPermissions,
}: verifyJWTArguments) => {
let tokenClaims: DashboardTokenPayload;
const ERROR_MESSAGE = "JWT verification failed:";
try {
tokenClaims = jose.decodeJwt(token as string) as DashboardTokenPayload;
debug("Token Claims decoded from jwt");
} catch (e) {
debug("Token Claims could not be decoded from JWT, will respond with Bad Request");
throw new Error(`${ERROR_MESSAGE} Could not decode authorization token.`);
}
try {
verifyTokenExpiration(tokenClaims);
} catch (e) {
throw new Error(`${ERROR_MESSAGE} ${(e as Error).message}`);
}
if (tokenClaims.app !== appId) {
debug(
"Resolved App ID value from token to be different than in request, will respond with Bad Request"
);
throw new Error(`${ERROR_MESSAGE} Token's app property is different than app ID.`);
}
if (!hasPermissionsInJwtToken(tokenClaims, requiredPermissions)) {
debug("Token did not meet requirements for permissions: %s", requiredPermissions);
throw new Error(`${ERROR_MESSAGE} Token's permissions are not sufficient.`);
}
try {
debug("Trying to create JWKS");
const JWKS = jose.createRemoteJWKSet(new URL(getJwksUrlFromSaleorApiUrl(saleorApiUrl)));
debug("Trying to compare JWKS with token");
await jose.jwtVerify(token, JWKS);
} catch (e) {
debug("Failure: %s", e);
debug("Will return with Bad Request");
console.error(e);
throw new Error(`${ERROR_MESSAGE} JWT signature verification failed.`);
}
};