oauth-entra-id
Version:
🛡️ A Secure, Performant, and Feature-Rich OAuth 2.0 Integration for Microsoft Entra ID — Fully Abstracted and Production-Ready.
86 lines (84 loc) • 3.54 kB
JavaScript
import { $jwtClientConfig, OAuthError, zJwt, $err, $verifyJwt, zMethods, $stringErr, $mapAndFilter, $getExpiry, TIME_SKEW, $ok } from './chunk-VN6QIMDR.js';
export { OAuthError, OAuthProvider } from './chunk-VN6QIMDR.js';
// src/lite.ts
var LiteProvider = class {
/**
* @param configuration The OAuth configuration object:
* - `azure`: clientId, tenantId, and optional clientSecret with B2B apps.
* @throws {OAuthError} if the config fails validation or has duplicate service names
*/
constructor(configuration) {
const result = $jwtClientConfig(configuration);
if (result.error) throw new OAuthError(result.error);
this.azure = result.azure;
this.jwksClient = result.jwksClient;
}
/**
* Verifies a JWT token and extracts its payload and metadata.
* @param jwtToken - Microsoft Entra ID Access Token (JWT).
* @returns A result containing the JWT payload and metadata.
*/
async $verifyJwt(jwtToken) {
const { data: token, error } = zJwt.safeParse(jwtToken);
if (error) return $err({ msg: "Unauthorized", desc: "Access token is required", status: 401 });
return await $verifyJwt({ jwtToken: token, azure: this.azure, jwksClient: this.jwksClient });
}
async tryGetB2BToken(params) {
if (!this.azure.b2bApps || !this.azure.cca) {
return $err({ msg: "Invalid configuration", desc: "B2B apps are not configured", status: 500 });
}
const { data: parsedParams, error: paramsError } = zMethods.tryGetB2BToken.safeParse(params);
if (paramsError) return $err({ msg: "Invalid Params", desc: $stringErr(paramsError) });
const apps = parsedParams.apps.map((app) => this.azure.b2bApps?.get(app)).filter((app) => !!app);
if (!apps || apps.length === 0) return $err({ msg: "Invalid Params", desc: "B2B app not found", status: 400 });
try {
const results = await $mapAndFilter(apps, async (app) => {
if (app.token && app.exp > Date.now() / 1e3) {
return {
clientId: this.azure.clientId,
appName: app.appName,
appId: app.aud,
token: app.token,
msalResponse: app.msalResponse,
isCached: true,
expiresAt: app.exp
};
}
const msalResponse = await this.azure.cca?.acquireTokenByClientCredential({
scopes: [app.scope],
skipCache: true
});
if (!msalResponse) return null;
const { clientId, exp, error: audError } = $getExpiry(msalResponse.accessToken);
if (audError) return null;
this.azure.b2bApps?.set(app.appName, {
appName: app.appName,
scope: app.scope,
token: msalResponse.accessToken,
exp: exp - TIME_SKEW,
aud: clientId,
msalResponse
});
return {
clientId: this.azure.clientId,
appName: app.appName,
appId: clientId,
token: msalResponse.accessToken,
msalResponse,
isCached: false,
expiresAt: 0
};
});
if (!results || results.length === 0) {
return $err({ msg: "Invalid Params", desc: "Failed to get B2B token" });
}
return $ok("app" in params ? { result: results[0] } : { results });
} catch (error) {
if (error instanceof OAuthError) return $err(error);
return $err({ msg: "Invalid Params", desc: `Failed to get B2B token: ${$stringErr(error)}` });
}
}
};
export { LiteProvider };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map