@takodotid/azure-rest 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +0,0 @@
1
- /**
2
- * Represents an Azure access token and its expiration.
3
- */
4
- export type Credential = { accessToken: string; clientId?: string; expiresAt: Date; tokenType: string };
5
-
6
- /**
7
- * Abstract credential class for acquiring Azure tokens.
8
- * Implement this to provide custom authentication logic.
9
- */
10
- export abstract class AzureCredential {
11
- /**
12
- * Gets an Azure access token for the given scope.
13
- * @param scope The resource or scope for which the token is requested
14
- * @returns A promise resolving to an AzureToken
15
- */
16
- public abstract getToken(scope: string): Promise<Credential>;
17
- }
@@ -1,34 +0,0 @@
1
- import { AzureCliCredential } from "./AzureCliCredential.js";
2
- import type { AzureCredential } from "./AzureCredential.js";
3
- import { ManagedIdentityCredential } from "./ManagedIdentityCredential.js";
4
- import { ServicePrincipalCredential } from "./ServicePrincipalCredential.js";
5
- import { WorkloadIdentityCredential } from "./WorkloadIdentityCredential.js";
6
-
7
- const credentialChain = [WorkloadIdentityCredential, ManagedIdentityCredential, ServicePrincipalCredential, AzureCliCredential];
8
-
9
- /**
10
- * DefaultChainedCredential tries multiple credential providers in order until one succeeds.
11
- *
12
- * The chain is: WorkloadIdentityCredential → ManagedIdentityCredential → ServicePrincipalCredential → AzureCliCredential.
13
- * Useful for local dev, CI, and cloud environments with minimal config.
14
- */
15
- export class DefaultChainedCredential implements AzureCredential {
16
- /**
17
- * Attempts to get an Azure access token using the first available credential in the chain.
18
- * @param scope The resource scope for the token
19
- * @returns An object with token and expiresAt
20
- * @throws If all credential providers fail
21
- */
22
- public async getToken(scope: string) {
23
- const errors: { name: string; error: Error }[] = [];
24
- for (const Credential of credentialChain) {
25
- try {
26
- return await Credential.fromEnv().getToken(scope);
27
- } catch (error) {
28
- errors.push({ error: error as Error, name: Credential.name });
29
- }
30
- }
31
-
32
- throw new Error(`Failed to get token, errors:\n${errors.map(err => `[${err.name}] ${err.error.message}`).join("\n")}`);
33
- }
34
- }
@@ -1,75 +0,0 @@
1
- import type { AzureCredential } from "./AzureCredential.js";
2
- import type { OAuth2TokenResponse } from "./ServicePrincipalCredential.js";
3
-
4
- /**
5
- * Options for configuring ManagedIdentityCredential.
6
- *
7
- * @property clientId - (Optional) The user-assigned managed identity client ID
8
- */
9
- export type ManagedIdentityCredentialOptions = {
10
- clientId?: string;
11
- };
12
-
13
- /**
14
- * AzureCredential implementation for Azure Managed Identity (MSI).
15
- *
16
- * Supports both system-assigned and user-assigned managed identities.
17
- * Works on Azure VM, App Service, Container Apps, etc.
18
- */
19
- export class ManagedIdentityCredential implements AzureCredential {
20
- /**
21
- * @param options Managed identity credential options
22
- */
23
- public constructor(public options: ManagedIdentityCredentialOptions = {}) {}
24
-
25
- /**
26
- * Gets an Azure access token using the managed identity endpoint.
27
- * @param scope The resource scope for the token
28
- * @returns An object with token and expiresAt
29
- * @throws If the endpoint is unavailable or token request fails
30
- */
31
- public async getToken(scope: string) {
32
- const endpoint = process.env.AZURE_MANAGED_IDENTITY_ENDPOINT || process.env.IDENTITY_ENDPOINT || "http://169.254.169.254/metadata/identity/oauth2/token";
33
- const apiVersion = "2018-02-01";
34
- const params = new URLSearchParams({
35
- resource: scope.replace(".default", ""),
36
- apiVersion
37
- });
38
- if (this.options.clientId) {
39
- params.set("client_id", this.options.clientId);
40
- }
41
-
42
- const url = `${endpoint}?${params.toString()}`;
43
- const headers = { Metadata: "true" };
44
-
45
- const response = await fetch(url, { headers });
46
- if (!response.ok) {
47
- throw new Error(`ManagedIdentityCredential: Failed to get token: ${await response.text()}`);
48
- }
49
-
50
- const data = (await response.json()) as OAuth2TokenResponse;
51
- return {
52
- accessToken: data.access_token,
53
- clientId: data.client_id,
54
- expiresAt: new Date(data.expires_on ? Number(data.expires_on) * 1000 : Date.now() + 60 * 60 * 1000), // fallback 1h
55
- tokenType: data.token_type
56
- };
57
- }
58
-
59
- /**
60
- * Instantiates ManagedIdentityCredential using environment variables.
61
- * @returns ManagedIdentityCredential instance
62
- */
63
- public static fromEnv() {
64
- return new ManagedIdentityCredential({ clientId: process.env.AZURE_CLIENT_ID });
65
- }
66
- }
67
-
68
- declare global {
69
- namespace NodeJS {
70
- interface ProcessEnv {
71
- AZURE_MANAGED_IDENTITY_ENDPOINT?: string;
72
- IDENTITY_ENDPOINT?: string;
73
- }
74
- }
75
- }
@@ -1,132 +0,0 @@
1
- import { URLSearchParams } from "node:url";
2
- import type { AzureCredential } from "./AzureCredential.js";
3
-
4
- /**
5
- * The OAuth2 token response returned by Azure AD and Managed Identity endpoints.
6
- *
7
- * @property access_token - The access token string
8
- * @property client_id - The client/application ID (optional, present in MSI)
9
- * @property expires_in - Seconds until token expiry
10
- * @property expires_on - Expiry time (epoch seconds, as string)
11
- * @property ext_expires_in - Extended expiry in seconds
12
- * @property not_before - Not before time (epoch seconds, as string)
13
- * @property resource - The resource for which the token is issued
14
- * @property token_type - The type of token (usually 'Bearer')
15
- */
16
- export type OAuth2TokenResponse = {
17
- access_token: string;
18
- client_id?: string;
19
- expires_in: number;
20
- expires_on: string;
21
- ext_expires_in: number;
22
- not_before: string;
23
- resource: string;
24
- token_type: string;
25
- };
26
-
27
- /**
28
- * Options for configuring ServicePrincipalCredential.
29
- *
30
- * @property clientId - The Azure AD application (client) ID
31
- * @property clientSecret - The client secret or JWT assertion (for federated)
32
- * @property tenantId - The Azure AD tenant ID
33
- * @property authorityHost - (Optional) The Azure AD authority host
34
- * @property federated - Whether to use federated (JWT) auth
35
- */
36
- export type ServicePrincipalCredentialOption = {
37
- clientId: string;
38
- clientSecret?: string;
39
- tenantId: string;
40
- authorityHost?: string;
41
- federated: boolean;
42
- };
43
-
44
- /**
45
- * AzureCredential implementation for authenticating with a Service Principal (client secret or federated/JWT).
46
- */
47
- export class ServicePrincipalCredential implements AzureCredential {
48
- /**
49
- * @param options Service principal credential options
50
- */
51
- public constructor(public options: ServicePrincipalCredentialOption) {}
52
-
53
- /**
54
- * Gets an Azure access token using the service principal credentials.
55
- * @param scope The resource scope for the token
56
- * @returns An object with token and expiresAt
57
- * @throws If client secret is missing or token request fails
58
- */
59
- public async getToken(scope: string) {
60
- if (!this.options.clientSecret) throw new Error("ServicePrincipalCredential: The client secret is not provided.");
61
-
62
- // Remove trailing slash from identityAuthorityHost
63
- const url = [this.options.authorityHost?.replace(/\/$/, "") ?? "https://login.microsoftonline.com", `${this.options.tenantId}/oauth2/v2.0/token`].join("/");
64
-
65
- try {
66
- const searchParams = {
67
- client_id: this.options.clientId,
68
- grant_type: "client_credentials",
69
- scope
70
- };
71
-
72
- // If federated, use client_assertion and client_assertion_type
73
- // Otherwise, use client_secret
74
- if (this.options.federated) {
75
- Object.assign(searchParams, {
76
- client_assertion: this.options.clientSecret,
77
- client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
78
- });
79
- } else {
80
- Object.assign(searchParams, {
81
- client_secret: this.options.clientSecret
82
- });
83
- }
84
- const response = await fetch(url, {
85
- method: "POST",
86
- headers: {
87
- Accept: "application/json",
88
- "Content-Type": "application/x-www-form-urlencoded"
89
- },
90
- body: new URLSearchParams(searchParams)
91
- });
92
-
93
- if (!response.ok) {
94
- throw new Error(`Failed to get token: ${await response.text()}`);
95
- }
96
-
97
- const data = (await response.json()) as OAuth2TokenResponse;
98
-
99
- return {
100
- accessToken: data.access_token,
101
- clientId: data.client_id ?? this.options.clientId,
102
- expiresAt: new Date(Date.now() + data.expires_in * 1_000),
103
- tokenType: data.token_type
104
- };
105
- } catch (error) {
106
- throw new Error(`Failed to get token: ${(error as Error).stack}`);
107
- }
108
- }
109
-
110
- /**
111
- * Instantiates ServicePrincipalCredential using environment variables.
112
- * @returns ServicePrincipalCredential instance
113
- */
114
- public static fromEnv() {
115
- return new ServicePrincipalCredential({
116
- clientId: process.env.AZURE_CLIENT_ID,
117
- clientSecret: process.env.AZURE_CLIENT_SECRET,
118
- tenantId: process.env.AZURE_TENANT_ID,
119
- federated: false
120
- });
121
- }
122
- }
123
-
124
- declare global {
125
- namespace NodeJS {
126
- interface ProcessEnv {
127
- AZURE_CLIENT_ID: string;
128
- AZURE_CLIENT_SECRET: string;
129
- AZURE_TENANT_ID: string;
130
- }
131
- }
132
- }
@@ -1,71 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import type { AzureCredential } from "./AzureCredential.js";
3
- import { ServicePrincipalCredential } from "./ServicePrincipalCredential.js";
4
-
5
- /**
6
- * Options for configuring WorkloadIdentityCredential.
7
- *
8
- * @property clientId - The Azure AD application (client) ID
9
- * @property federatedTokenFile - Path to the federated token file (OIDC/JWT)
10
- * @property tenantId - The Azure AD tenant ID
11
- * @property authorityHost - (Optional) The Azure AD authority host
12
- */
13
- export type WorkloadIdentityCredentialOption = {
14
- clientId: string;
15
- federatedTokenFile: string;
16
- tenantId: string;
17
- authorityHost?: string;
18
- };
19
-
20
- /**
21
- * AzureCredential implementation for Azure Workload Identity (OIDC federated token).
22
- *
23
- * Reads a federated token from file and authenticates as a service principal using JWT assertion.
24
- */
25
- export class WorkloadIdentityCredential implements AzureCredential {
26
- /**
27
- * @param options Workload identity credential options
28
- */
29
- public constructor(public options: WorkloadIdentityCredentialOption) {}
30
-
31
- /**
32
- * Gets an Azure access token using the federated token file.
33
- * @param scope The resource scope for the token
34
- * @returns An object with token and expiresAt
35
- * @throws If the federated token file does not exist
36
- */
37
- public async getToken(scope: string) {
38
- if (!existsSync(this.options.federatedTokenFile)) {
39
- throw new Error("WorkloadIdentityCredential: The federated token file does not exist.");
40
- }
41
-
42
- const token = readFileSync(this.options.federatedTokenFile, "utf-8");
43
- const servicePrincipal = new ServicePrincipalCredential({ ...this.options, clientSecret: token, federated: true });
44
-
45
- return servicePrincipal.getToken(scope);
46
- }
47
-
48
- /**
49
- * Instantiates WorkloadIdentityCredential using environment variables.
50
- * @returns WorkloadIdentityCredential instance
51
- */
52
- public static fromEnv() {
53
- return new WorkloadIdentityCredential({
54
- authorityHost: process.env.AZURE_AUTHORITY_HOST,
55
- clientId: process.env.AZURE_CLIENT_ID,
56
- federatedTokenFile: process.env.AZURE_FEDERATED_TOKEN_FILE,
57
- tenantId: process.env.AZURE_TENANT_ID
58
- });
59
- }
60
- }
61
-
62
- declare global {
63
- namespace NodeJS {
64
- interface ProcessEnv {
65
- AZURE_AUTHORITY_HOST: string;
66
- AZURE_CLIENT_ID: string;
67
- AZURE_FEDERATED_TOKEN_FILE: string;
68
- AZURE_TENANT_ID: string;
69
- }
70
- }
71
- }
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": ".",
4
- "lib": ["ES2022"],
5
- "module": "node18",
6
- "moduleResolution": "nodenext",
7
- "target": "es2022",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "declaration": true,
12
- "noEmit": true
13
- },
14
- "include": ["src"]
15
- }
package/tsup.config.ts DELETED
@@ -1,10 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.ts"],
5
- format: ["esm", "cjs"],
6
- dts: true,
7
- platform: "node",
8
- target: "es2022",
9
- sourcemap: true
10
- });