@clerk/shared
Version:
Internal package utils used by the Clerk SDKs
103 lines (101 loc) • 3.04 kB
JavaScript
import { splitByScope } from "./authorization.mjs";
//#region src/jwtPayloadParser.ts
const decimalToBinaryBits = (decimal, minimumLength) => {
if (!/^\d+$/.test(decimal)) return;
let remaining = decimal.replace(/^0+/, "") || "0";
const bits = [];
while (remaining !== "0") {
let quotient = "";
let remainder = 0;
for (let i = 0; i < remaining.length; i++) {
const value = remainder * 10 + remaining.charCodeAt(i) - 48;
const quotientDigit = Math.floor(value / 2);
if (quotient || quotientDigit !== 0) quotient += quotientDigit;
remainder = value % 2;
}
bits.push(remainder);
remaining = quotient || "0";
}
if (bits.length === 0) bits.push(0);
while (bits.length < minimumLength) bits.push(0);
return bits;
};
const parsePermissions = ({ per, fpm }) => {
if (!per || !fpm) return {
permissions: [],
featurePermissionMap: []
};
const permissions = per.split(",").map((p) => p.trim());
return {
permissions,
featurePermissionMap: fpm.split(",").map((permission) => decimalToBinaryBits(permission.trim(), permissions.length) ?? [])
};
};
/**
*
*/
function buildOrgPermissions({ features, permissions, featurePermissionMap }) {
if (!features || !permissions || !featurePermissionMap) return [];
const orgPermissions = [];
for (let featureIndex = 0; featureIndex < features.length; featureIndex++) {
const feature = features[featureIndex];
if (featureIndex >= featurePermissionMap.length) continue;
const permissionBits = featurePermissionMap[featureIndex];
if (!permissionBits) continue;
for (let permIndex = 0; permIndex < permissionBits.length && permIndex < permissions.length; permIndex++) if (permissionBits[permIndex] === 1) orgPermissions.push(`org:${feature}:${permissions[permIndex]}`);
}
return orgPermissions;
}
/**
* Resolves the signed-in auth state from JWT claims.
*
* @experimental
*/
const __experimental_JWTPayloadToAuthObjectProperties = (claims) => {
let orgId;
let orgRole;
let orgSlug;
let orgPermissions;
const factorVerificationAge = claims.fva ?? null;
const sessionStatus = claims.sts ?? null;
switch (claims.v) {
case 2:
if (claims.o) {
orgId = claims.o?.id;
orgSlug = claims.o?.slg;
if (claims.o?.rol) orgRole = `org:${claims.o?.rol}`;
const { org } = splitByScope(claims.fea);
const { permissions, featurePermissionMap } = parsePermissions({
per: claims.o?.per,
fpm: claims.o?.fpm
});
orgPermissions = buildOrgPermissions({
features: org,
featurePermissionMap,
permissions
});
}
break;
default:
orgId = claims.org_id;
orgRole = claims.org_role;
orgSlug = claims.org_slug;
orgPermissions = claims.org_permissions;
break;
}
return {
sessionClaims: claims,
sessionId: claims.sid,
sessionStatus,
actor: claims.act,
userId: claims.sub,
orgId,
orgRole,
orgSlug,
orgPermissions,
factorVerificationAge
};
};
//#endregion
export { __experimental_JWTPayloadToAuthObjectProperties, parsePermissions };
//# sourceMappingURL=jwtPayloadParser.mjs.map