@saleor/app-sdk
Version:
SDK for building great Saleor Apps
130 lines (117 loc) • 5.36 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunkDE4A7PETjs = require('./chunk-DE4A7PET.js');
// src/auth/verify-jwt.ts
var _jose = require('jose'); var jose = _interopRequireWildcard(_jose); var jose2 = _interopRequireWildcard(_jose);
// src/auth/has-permissions-in-jwt-token.ts
var debug = _chunkDE4A7PETjs.createDebug.call(void 0, "checkJwtPermissions");
var hasPermissionsInJwtToken = (tokenData, permissionsToCheckAgainst) => {
debug(`Permissions required ${permissionsToCheckAgainst}`);
if (!_optionalChain([permissionsToCheckAgainst, 'optionalAccess', _ => _.length])) {
debug("No permissions specified, check passed");
return true;
}
const userPermissions = _optionalChain([tokenData, 'optionalAccess', _2 => _2.user_permissions]) || void 0;
if (!_optionalChain([userPermissions, 'optionalAccess', _3 => _3.length])) {
debug("User has no permissions assigned. Rejected");
return false;
}
const arePermissionsSatisfied = permissionsToCheckAgainst.every(
(permission) => userPermissions.includes(permission)
);
if (!arePermissionsSatisfied) {
debug("Permissions check not passed");
return false;
}
debug("Permissions check successful");
return true;
};
// src/auth/verify-token-expiration.ts
var debug2 = _chunkDE4A7PETjs.createDebug.call(void 0, "verify-token-expiration");
var verifyTokenExpiration = (token) => {
const tokenExpiration = token.exp;
const now = /* @__PURE__ */ new Date();
const nowTimestamp = now.valueOf();
if (!tokenExpiration) {
throw new Error('Missing "exp" field in token');
}
const tokenMsTimestamp = tokenExpiration * 1e3;
debug2(
"Comparing to days date: %s and token expiration date: %s",
now.toLocaleString(),
new Date(tokenMsTimestamp).toLocaleString()
);
if (tokenMsTimestamp <= nowTimestamp) {
throw new Error("Token is expired");
}
};
// src/auth/verify-jwt.ts
var debug3 = _chunkDE4A7PETjs.createDebug.call(void 0, "verify-jwt");
var verifyJWT = async ({
saleorApiUrl,
token,
appId,
requiredPermissions
}) => {
let tokenClaims;
const ERROR_MESSAGE = "JWT verification failed:";
try {
tokenClaims = jose.decodeJwt(token);
debug3("Token Claims decoded from jwt");
} catch (e) {
debug3("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.message}`);
}
if (tokenClaims.app !== appId) {
debug3(
"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)) {
debug3("Token did not meet requirements for permissions: %s", requiredPermissions);
throw new Error(`${ERROR_MESSAGE} Token's permissions are not sufficient.`);
}
try {
debug3("Trying to create JWKS");
const JWKS = jose.createRemoteJWKSet(new URL(getJwksUrlFromSaleorApiUrl(saleorApiUrl)));
debug3("Trying to compare JWKS with token");
await jose.jwtVerify(token, JWKS);
} catch (e) {
debug3("Failure: %s", e);
debug3("Will return with Bad Request");
console.error(e);
throw new Error(`${ERROR_MESSAGE} JWT signature verification failed.`);
}
};
// src/auth/verify-signature.ts
var debug4 = _chunkDE4A7PETjs.createDebug.call(void 0, "verify-signature");
var verifySignatureWithJwks = async (jwks, signature, rawBody) => {
const [header, , jwsSignature] = signature.split(".");
const jws = {
protected: header,
payload: rawBody,
signature: jwsSignature
};
let localJwks;
try {
const parsedJWKS = JSON.parse(jwks);
localJwks = jose2.createLocalJWKSet(parsedJWKS);
} catch (e2) {
debug4("Could not create local JWKSSet from given data: %s", jwks);
throw new Error("JWKS verification failed - could not parse given JWKS");
}
try {
await jose2.flattenedVerify(jws, localJwks);
debug4("JWKS verified");
} catch (e3) {
debug4("JWKS verification failed");
throw new Error("JWKS verification failed");
}
};
var getJwksUrlFromSaleorApiUrl = (saleorApiUrl) => `${new URL(saleorApiUrl).origin}/.well-known/jwks.json`;
exports.verifyJWT = verifyJWT; exports.verifySignatureWithJwks = verifySignatureWithJwks; exports.getJwksUrlFromSaleorApiUrl = getJwksUrlFromSaleorApiUrl;