@portaidentity/sdk 0.1.0
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.
- package/README.md +224 -0
- package/dist/agent.d.ts +42 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +146 -0
- package/dist/agent.js.map +1 -0
- package/dist/auth/cli-auth.d.ts +83 -0
- package/dist/auth/cli-auth.d.ts.map +1 -0
- package/dist/auth/cli-auth.js +188 -0
- package/dist/auth/cli-auth.js.map +1 -0
- package/dist/auth/client-credentials-auth.d.ts +54 -0
- package/dist/auth/client-credentials-auth.d.ts.map +1 -0
- package/dist/auth/client-credentials-auth.js +147 -0
- package/dist/auth/client-credentials-auth.js.map +1 -0
- package/dist/auth/index.d.ts +20 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +16 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-auth.d.ts +40 -0
- package/dist/auth/token-auth.d.ts.map +1 -0
- package/dist/auth/token-auth.js +44 -0
- package/dist/auth/token-auth.js.map +1 -0
- package/dist/auth/types.d.ts +28 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +11 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/browser.d.ts +12 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +12 -0
- package/dist/browser.js.map +1 -0
- package/dist/client.d.ts +52 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +52 -0
- package/dist/client.js.map +1 -0
- package/dist/domains/applications.d.ts +23 -0
- package/dist/domains/applications.d.ts.map +1 -0
- package/dist/domains/applications.js +59 -0
- package/dist/domains/applications.js.map +1 -0
- package/dist/domains/audit.d.ts +13 -0
- package/dist/domains/audit.d.ts.map +1 -0
- package/dist/domains/audit.js +19 -0
- package/dist/domains/audit.js.map +1 -0
- package/dist/domains/branding.d.ts +16 -0
- package/dist/domains/branding.d.ts.map +1 -0
- package/dist/domains/branding.js +29 -0
- package/dist/domains/branding.js.map +1 -0
- package/dist/domains/bulk.d.ts +12 -0
- package/dist/domains/bulk.d.ts.map +1 -0
- package/dist/domains/bulk.js +14 -0
- package/dist/domains/bulk.js.map +1 -0
- package/dist/domains/clients.d.ts +22 -0
- package/dist/domains/clients.d.ts.map +1 -0
- package/dist/domains/clients.js +55 -0
- package/dist/domains/clients.js.map +1 -0
- package/dist/domains/config.d.ts +14 -0
- package/dist/domains/config.d.ts.map +1 -0
- package/dist/domains/config.js +23 -0
- package/dist/domains/config.js.map +1 -0
- package/dist/domains/custom-claims.d.ts +17 -0
- package/dist/domains/custom-claims.d.ts.map +1 -0
- package/dist/domains/custom-claims.js +35 -0
- package/dist/domains/custom-claims.js.map +1 -0
- package/dist/domains/exports.d.ts +12 -0
- package/dist/domains/exports.d.ts.map +1 -0
- package/dist/domains/exports.js +20 -0
- package/dist/domains/exports.js.map +1 -0
- package/dist/domains/helpers.d.ts +27 -0
- package/dist/domains/helpers.d.ts.map +1 -0
- package/dist/domains/helpers.js +46 -0
- package/dist/domains/helpers.js.map +1 -0
- package/dist/domains/imports.d.ts +12 -0
- package/dist/domains/imports.d.ts.map +1 -0
- package/dist/domains/imports.js +14 -0
- package/dist/domains/imports.js.map +1 -0
- package/dist/domains/index.d.ts +45 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +46 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/keys.d.ts +14 -0
- package/dist/domains/keys.d.ts.map +1 -0
- package/dist/domains/keys.js +23 -0
- package/dist/domains/keys.js.map +1 -0
- package/dist/domains/organizations.d.ts +33 -0
- package/dist/domains/organizations.d.ts.map +1 -0
- package/dist/domains/organizations.js +69 -0
- package/dist/domains/organizations.js.map +1 -0
- package/dist/domains/permissions.d.ts +16 -0
- package/dist/domains/permissions.d.ts.map +1 -0
- package/dist/domains/permissions.js +31 -0
- package/dist/domains/permissions.js.map +1 -0
- package/dist/domains/roles.d.ts +19 -0
- package/dist/domains/roles.d.ts.map +1 -0
- package/dist/domains/roles.js +41 -0
- package/dist/domains/roles.js.map +1 -0
- package/dist/domains/sessions.d.ts +17 -0
- package/dist/domains/sessions.d.ts.map +1 -0
- package/dist/domains/sessions.js +28 -0
- package/dist/domains/sessions.js.map +1 -0
- package/dist/domains/stats.d.ts +12 -0
- package/dist/domains/stats.d.ts.map +1 -0
- package/dist/domains/stats.js +14 -0
- package/dist/domains/stats.js.map +1 -0
- package/dist/domains/two-factor.d.ts +14 -0
- package/dist/domains/two-factor.d.ts.map +1 -0
- package/dist/domains/two-factor.js +24 -0
- package/dist/domains/two-factor.js.map +1 -0
- package/dist/domains/user-claims.d.ts +14 -0
- package/dist/domains/user-claims.d.ts.map +1 -0
- package/dist/domains/user-claims.js +24 -0
- package/dist/domains/user-claims.js.map +1 -0
- package/dist/domains/user-roles.d.ts +14 -0
- package/dist/domains/user-roles.d.ts.map +1 -0
- package/dist/domains/user-roles.js +24 -0
- package/dist/domains/user-roles.js.map +1 -0
- package/dist/domains/users.d.ts +25 -0
- package/dist/domains/users.d.ts.map +1 -0
- package/dist/domains/users.js +67 -0
- package/dist/domains/users.js.map +1 -0
- package/dist/errors/index.d.ts +110 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +206 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +12 -0
- package/dist/node.js.map +1 -0
- package/dist/pagination/index.d.ts +87 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +67 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/transport/browser-transport.d.ts +64 -0
- package/dist/transport/browser-transport.d.ts.map +1 -0
- package/dist/transport/browser-transport.js +96 -0
- package/dist/transport/browser-transport.js.map +1 -0
- package/dist/transport/node-transport.d.ts +51 -0
- package/dist/transport/node-transport.d.ts.map +1 -0
- package/dist/transport/node-transport.js +108 -0
- package/dist/transport/node-transport.js.map +1 -0
- package/dist/transport/types.d.ts +84 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +13 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/utils.d.ts +78 -0
- package/dist/transport/utils.d.ts.map +1 -0
- package/dist/transport/utils.js +126 -0
- package/dist/transport/utils.js.map +1 -0
- package/dist/types/applications.d.ts +48 -0
- package/dist/types/applications.d.ts.map +1 -0
- package/dist/types/applications.js +7 -0
- package/dist/types/applications.js.map +1 -0
- package/dist/types/audit.d.ts +31 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +7 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/branding.d.ts +13 -0
- package/dist/types/branding.d.ts.map +1 -0
- package/dist/types/branding.js +7 -0
- package/dist/types/branding.js.map +1 -0
- package/dist/types/bulk.d.ts +22 -0
- package/dist/types/bulk.d.ts.map +1 -0
- package/dist/types/bulk.js +7 -0
- package/dist/types/bulk.js.map +1 -0
- package/dist/types/clients.d.ts +70 -0
- package/dist/types/clients.d.ts.map +1 -0
- package/dist/types/clients.js +7 -0
- package/dist/types/clients.js.map +1 -0
- package/dist/types/common.d.ts +75 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +7 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/custom-claims.d.ts +48 -0
- package/dist/types/custom-claims.d.ts.map +1 -0
- package/dist/types/custom-claims.js +7 -0
- package/dist/types/custom-claims.js.map +1 -0
- package/dist/types/exports.d.ts +14 -0
- package/dist/types/exports.d.ts.map +1 -0
- package/dist/types/exports.js +7 -0
- package/dist/types/exports.js.map +1 -0
- package/dist/types/imports.d.ts +31 -0
- package/dist/types/imports.d.ts.map +1 -0
- package/dist/types/imports.js +7 -0
- package/dist/types/imports.js.map +1 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/keys.d.ts +14 -0
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/keys.js +7 -0
- package/dist/types/keys.js.map +1 -0
- package/dist/types/organizations.d.ts +47 -0
- package/dist/types/organizations.d.ts.map +1 -0
- package/dist/types/organizations.js +7 -0
- package/dist/types/organizations.js.map +1 -0
- package/dist/types/permissions.d.ts +23 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +7 -0
- package/dist/types/permissions.js.map +1 -0
- package/dist/types/roles.d.ts +30 -0
- package/dist/types/roles.d.ts.map +1 -0
- package/dist/types/roles.js +7 -0
- package/dist/types/roles.js.map +1 -0
- package/dist/types/sessions.d.ts +25 -0
- package/dist/types/sessions.d.ts.map +1 -0
- package/dist/types/sessions.js +7 -0
- package/dist/types/sessions.js.map +1 -0
- package/dist/types/stats.d.ts +18 -0
- package/dist/types/stats.d.ts.map +1 -0
- package/dist/types/stats.js +7 -0
- package/dist/types/stats.js.map +1 -0
- package/dist/types/two-factor.d.ts +14 -0
- package/dist/types/two-factor.d.ts.map +1 -0
- package/dist/types/two-factor.js +7 -0
- package/dist/types/two-factor.js.map +1 -0
- package/dist/types/user-claims.d.ts +16 -0
- package/dist/types/user-claims.d.ts.map +1 -0
- package/dist/types/user-claims.js +7 -0
- package/dist/types/user-claims.js.map +1 -0
- package/dist/types/user-roles.d.ts +17 -0
- package/dist/types/user-roles.d.ts.map +1 -0
- package/dist/types/user-roles.js +7 -0
- package/dist/types/user-roles.js.map +1 -0
- package/dist/types/users.d.ts +53 -0
- package/dist/types/users.d.ts.map +1 -0
- package/dist/types/users.js +7 -0
- package/dist/types/users.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CliAuth — reuse Porta CLI stored credentials as an authentication provider.
|
|
3
|
+
*
|
|
4
|
+
* Reads credentials from `~/.porta/credentials.json` (the file created by
|
|
5
|
+
* `porta login`) and uses them for API authentication. Handles token expiry
|
|
6
|
+
* detection and automatic refresh via the refresh_token grant.
|
|
7
|
+
*
|
|
8
|
+
* Key behaviors:
|
|
9
|
+
* - Reads credentials file on first `getToken()` call, caches in memory
|
|
10
|
+
* - Checks `expiresAt` with 60s safety buffer to detect near-expired tokens
|
|
11
|
+
* - `refreshToken()` re-reads the file (CLI may have refreshed) then
|
|
12
|
+
* POSTs refresh_token grant to the token endpoint
|
|
13
|
+
* - Does NOT write back to the credentials file — only the CLI writes
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createCliAuth } from '@portaidentity/sdk';
|
|
18
|
+
*
|
|
19
|
+
* // Uses default ~/.porta/credentials.json
|
|
20
|
+
* const auth = createCliAuth();
|
|
21
|
+
* const client = createPortaClient({ baseUrl: '...', auth });
|
|
22
|
+
*
|
|
23
|
+
* // Custom path for testing
|
|
24
|
+
* const auth2 = createCliAuth({ credentialsPath: '/tmp/test-creds.json' });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @module auth/cli-auth
|
|
28
|
+
*/
|
|
29
|
+
import { readFile } from 'node:fs/promises';
|
|
30
|
+
import { join } from 'node:path';
|
|
31
|
+
import { homedir } from 'node:os';
|
|
32
|
+
import { PortaAuthenticationError } from '../errors/index.js';
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Constants
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/** Default path to the credentials file */
|
|
37
|
+
const DEFAULT_CREDENTIALS_DIR = '.porta';
|
|
38
|
+
const DEFAULT_CREDENTIALS_FILE = 'credentials.json';
|
|
39
|
+
/**
|
|
40
|
+
* Safety buffer (in seconds) for token expiry checks.
|
|
41
|
+
* Matches the CLI's 60-second buffer to avoid clock skew issues.
|
|
42
|
+
*/
|
|
43
|
+
const EXPIRY_BUFFER_SECONDS = 60;
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Factory
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Creates a CLI credentials authentication provider.
|
|
49
|
+
*
|
|
50
|
+
* Returns an {@link AuthProvider} that reads the Porta CLI's stored
|
|
51
|
+
* credentials file and uses them for API authentication. The provider
|
|
52
|
+
* caches credentials in memory and handles token refresh transparently.
|
|
53
|
+
*
|
|
54
|
+
* **Important:** This provider does NOT write back to the credentials file.
|
|
55
|
+
* Only the CLI (`porta login`, `porta logout`) manages the file. The SDK
|
|
56
|
+
* refreshes tokens in-memory only.
|
|
57
|
+
*
|
|
58
|
+
* @param options - Optional configuration (credentials file path)
|
|
59
|
+
* @returns An AuthProvider backed by CLI stored credentials
|
|
60
|
+
*/
|
|
61
|
+
export function createCliAuth(options = {}) {
|
|
62
|
+
const credentialsPath = options.credentialsPath ??
|
|
63
|
+
join(homedir(), DEFAULT_CREDENTIALS_DIR, DEFAULT_CREDENTIALS_FILE);
|
|
64
|
+
/** In-memory cached credentials — null until first read */
|
|
65
|
+
let cached = null;
|
|
66
|
+
/**
|
|
67
|
+
* Reads and parses the credentials file from disk.
|
|
68
|
+
*
|
|
69
|
+
* @throws PortaAuthenticationError if file not found or unreadable
|
|
70
|
+
*/
|
|
71
|
+
async function readCredentialsFile() {
|
|
72
|
+
try {
|
|
73
|
+
const content = await readFile(credentialsPath, 'utf-8');
|
|
74
|
+
const parsed = JSON.parse(content);
|
|
75
|
+
// Validate minimum required fields
|
|
76
|
+
if (!parsed.accessToken || !parsed.server || !parsed.orgSlug) {
|
|
77
|
+
throw new PortaAuthenticationError({
|
|
78
|
+
message: `Invalid credentials file at ${credentialsPath}: missing required fields. Run 'porta login' to re-authenticate.`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// File not found — user hasn't logged in yet
|
|
85
|
+
if (error.code === 'ENOENT') {
|
|
86
|
+
throw new PortaAuthenticationError({
|
|
87
|
+
message: `Credentials file not found at ${credentialsPath}. Run 'porta login' first.`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// Re-throw PortaAuthenticationError (from validation above or nested)
|
|
91
|
+
if (error instanceof PortaAuthenticationError) {
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
// JSON parse error or other read failure
|
|
95
|
+
throw new PortaAuthenticationError({
|
|
96
|
+
message: `Failed to read credentials file at ${credentialsPath}: ${error.message}`,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Checks whether the access token is expired or about to expire.
|
|
102
|
+
* Uses a 60-second safety buffer matching the CLI's behavior.
|
|
103
|
+
*/
|
|
104
|
+
function isTokenExpired(creds) {
|
|
105
|
+
if (!creds.expiresAt)
|
|
106
|
+
return false;
|
|
107
|
+
const expiresAtMs = new Date(creds.expiresAt).getTime();
|
|
108
|
+
return Date.now() >= expiresAtMs - EXPIRY_BUFFER_SECONDS * 1000;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Refreshes the access token using the refresh_token grant.
|
|
112
|
+
*
|
|
113
|
+
* POSTs to the OIDC token endpoint (`/{orgSlug}/token`) with
|
|
114
|
+
* grant_type=refresh_token. Updates the in-memory cache but does
|
|
115
|
+
* NOT write back to the credentials file.
|
|
116
|
+
*
|
|
117
|
+
* @throws PortaAuthenticationError if refresh fails or missing refresh_token
|
|
118
|
+
*/
|
|
119
|
+
async function refreshWithGrant(creds) {
|
|
120
|
+
if (!creds.refreshToken) {
|
|
121
|
+
throw new PortaAuthenticationError({
|
|
122
|
+
message: "Cannot refresh token: no refresh_token available. Run 'porta login' again.",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// Construct token endpoint from server URL and org slug
|
|
126
|
+
const tokenUrl = `${creds.server}/${creds.orgSlug}/token`;
|
|
127
|
+
const body = new URLSearchParams({
|
|
128
|
+
grant_type: 'refresh_token',
|
|
129
|
+
client_id: creds.clientId,
|
|
130
|
+
refresh_token: creds.refreshToken,
|
|
131
|
+
});
|
|
132
|
+
let response;
|
|
133
|
+
try {
|
|
134
|
+
response = await fetch(tokenUrl, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
137
|
+
body: body.toString(),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new PortaAuthenticationError({
|
|
142
|
+
message: `Token refresh request failed: ${error.message}. Run 'porta login' again.`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
throw new PortaAuthenticationError({
|
|
147
|
+
message: `Token refresh failed (${response.status}). Run 'porta login' again.`,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const data = (await response.json());
|
|
151
|
+
if (!data.access_token) {
|
|
152
|
+
throw new PortaAuthenticationError({
|
|
153
|
+
message: "Token refresh response missing access_token. Run 'porta login' again.",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Update in-memory cache with new tokens (don't write to file)
|
|
157
|
+
cached = {
|
|
158
|
+
...creds,
|
|
159
|
+
accessToken: data.access_token,
|
|
160
|
+
// Preserve existing tokens if server doesn't rotate them
|
|
161
|
+
refreshToken: data.refresh_token ?? creds.refreshToken,
|
|
162
|
+
idToken: data.id_token ?? creds.idToken,
|
|
163
|
+
expiresAt: data.expires_in
|
|
164
|
+
? new Date(Date.now() + data.expires_in * 1000).toISOString()
|
|
165
|
+
: creds.expiresAt,
|
|
166
|
+
};
|
|
167
|
+
return data.access_token;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
async getToken() {
|
|
171
|
+
// Read from file on first call
|
|
172
|
+
if (!cached) {
|
|
173
|
+
cached = await readCredentialsFile();
|
|
174
|
+
}
|
|
175
|
+
// If expired, try to refresh using the refresh_token grant
|
|
176
|
+
if (isTokenExpired(cached)) {
|
|
177
|
+
return refreshWithGrant(cached);
|
|
178
|
+
}
|
|
179
|
+
return cached.accessToken;
|
|
180
|
+
},
|
|
181
|
+
async refreshToken() {
|
|
182
|
+
// Re-read from file — the CLI may have refreshed since we last read
|
|
183
|
+
cached = await readCredentialsFile();
|
|
184
|
+
return refreshWithGrant(cached);
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=cli-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClientCredentialsAuth — OIDC client_credentials flow authentication provider.
|
|
3
|
+
*
|
|
4
|
+
* Implements the OAuth2 Client Credentials grant for machine-to-machine
|
|
5
|
+
* authentication. Fetches access tokens from the OIDC token endpoint,
|
|
6
|
+
* caches them with expiry awareness, and deduplicates concurrent requests.
|
|
7
|
+
*
|
|
8
|
+
* Key behaviors:
|
|
9
|
+
* - Caches token and serves from cache until near-expiry (30s safety margin)
|
|
10
|
+
* - Concurrent `getToken()` calls share a single in-flight fetch (dedup)
|
|
11
|
+
* - `refreshToken()` clears cache and forces a new token fetch
|
|
12
|
+
* - Uses native `fetch` — no `openid-client` dependency
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { createClientCredentialsAuth } from '@portaidentity/sdk';
|
|
17
|
+
*
|
|
18
|
+
* const auth = createClientCredentialsAuth({
|
|
19
|
+
* tokenEndpoint: 'https://porta.example.com/super-admin/token',
|
|
20
|
+
* clientId: 'my-service',
|
|
21
|
+
* clientSecret: 'secret123',
|
|
22
|
+
* });
|
|
23
|
+
* const client = createPortaClient({ baseUrl: '...', auth });
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module auth/client-credentials-auth
|
|
27
|
+
*/
|
|
28
|
+
import type { AuthProvider } from './types.js';
|
|
29
|
+
/**
|
|
30
|
+
* Options for creating a client credentials auth provider.
|
|
31
|
+
*/
|
|
32
|
+
export interface ClientCredentialsAuthOptions {
|
|
33
|
+
/** Token endpoint URL (e.g., 'https://porta.example.com/super-admin/token') */
|
|
34
|
+
tokenEndpoint: string;
|
|
35
|
+
/** Client ID */
|
|
36
|
+
clientId: string;
|
|
37
|
+
/** Client secret */
|
|
38
|
+
clientSecret: string;
|
|
39
|
+
/** Scopes to request (default: 'openid') */
|
|
40
|
+
scope?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a client credentials authentication provider.
|
|
44
|
+
*
|
|
45
|
+
* Returns an {@link AuthProvider} that fetches tokens from the OIDC token
|
|
46
|
+
* endpoint using the `client_credentials` grant. Tokens are cached and
|
|
47
|
+
* reused until near-expiry. Concurrent `getToken()` calls are deduplicated
|
|
48
|
+
* to avoid redundant token requests.
|
|
49
|
+
*
|
|
50
|
+
* @param options - Client credentials configuration
|
|
51
|
+
* @returns An AuthProvider with automatic token management
|
|
52
|
+
*/
|
|
53
|
+
export declare function createClientCredentialsAuth(options: ClientCredentialsAuthOptions): AuthProvider;
|
|
54
|
+
//# sourceMappingURL=client-credentials-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials-auth.d.ts","sourceRoot":"","sources":["../../src/auth/client-credentials-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+EAA+E;IAC/E,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4CD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,YAAY,CA0Gd"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClientCredentialsAuth — OIDC client_credentials flow authentication provider.
|
|
3
|
+
*
|
|
4
|
+
* Implements the OAuth2 Client Credentials grant for machine-to-machine
|
|
5
|
+
* authentication. Fetches access tokens from the OIDC token endpoint,
|
|
6
|
+
* caches them with expiry awareness, and deduplicates concurrent requests.
|
|
7
|
+
*
|
|
8
|
+
* Key behaviors:
|
|
9
|
+
* - Caches token and serves from cache until near-expiry (30s safety margin)
|
|
10
|
+
* - Concurrent `getToken()` calls share a single in-flight fetch (dedup)
|
|
11
|
+
* - `refreshToken()` clears cache and forces a new token fetch
|
|
12
|
+
* - Uses native `fetch` — no `openid-client` dependency
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { createClientCredentialsAuth } from '@portaidentity/sdk';
|
|
17
|
+
*
|
|
18
|
+
* const auth = createClientCredentialsAuth({
|
|
19
|
+
* tokenEndpoint: 'https://porta.example.com/super-admin/token',
|
|
20
|
+
* clientId: 'my-service',
|
|
21
|
+
* clientSecret: 'secret123',
|
|
22
|
+
* });
|
|
23
|
+
* const client = createPortaClient({ baseUrl: '...', auth });
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module auth/client-credentials-auth
|
|
27
|
+
*/
|
|
28
|
+
import { PortaAuthenticationError } from '../errors/index.js';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Constants
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Safety margin before token expiry (in milliseconds).
|
|
34
|
+
* Tokens are refreshed 30 seconds before their actual expiry to prevent
|
|
35
|
+
* race conditions with in-flight requests.
|
|
36
|
+
*/
|
|
37
|
+
const EXPIRY_SAFETY_MARGIN_MS = 30_000;
|
|
38
|
+
/**
|
|
39
|
+
* Default token lifetime (in seconds) if the token endpoint doesn't
|
|
40
|
+
* return an `expires_in` value. One hour matches common OIDC defaults.
|
|
41
|
+
*/
|
|
42
|
+
const DEFAULT_EXPIRES_IN_SECONDS = 3600;
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Factory
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Creates a client credentials authentication provider.
|
|
48
|
+
*
|
|
49
|
+
* Returns an {@link AuthProvider} that fetches tokens from the OIDC token
|
|
50
|
+
* endpoint using the `client_credentials` grant. Tokens are cached and
|
|
51
|
+
* reused until near-expiry. Concurrent `getToken()` calls are deduplicated
|
|
52
|
+
* to avoid redundant token requests.
|
|
53
|
+
*
|
|
54
|
+
* @param options - Client credentials configuration
|
|
55
|
+
* @returns An AuthProvider with automatic token management
|
|
56
|
+
*/
|
|
57
|
+
export function createClientCredentialsAuth(options) {
|
|
58
|
+
const { tokenEndpoint, clientId, clientSecret, scope = 'openid' } = options;
|
|
59
|
+
/** Cached token — null when no valid token is available */
|
|
60
|
+
let cachedToken = null;
|
|
61
|
+
/**
|
|
62
|
+
* In-flight token request promise — used for concurrent dedup.
|
|
63
|
+
* When multiple getToken() calls happen simultaneously, they all
|
|
64
|
+
* await the same promise instead of firing multiple HTTP requests.
|
|
65
|
+
*/
|
|
66
|
+
let inFlightRequest = null;
|
|
67
|
+
/**
|
|
68
|
+
* Fetches a new access token from the token endpoint.
|
|
69
|
+
* POSTs with grant_type=client_credentials and caches the result.
|
|
70
|
+
*
|
|
71
|
+
* @throws PortaAuthenticationError on non-OK response or missing access_token
|
|
72
|
+
*/
|
|
73
|
+
async function fetchToken() {
|
|
74
|
+
const body = new URLSearchParams({
|
|
75
|
+
grant_type: 'client_credentials',
|
|
76
|
+
client_id: clientId,
|
|
77
|
+
client_secret: clientSecret,
|
|
78
|
+
scope,
|
|
79
|
+
});
|
|
80
|
+
const response = await fetch(tokenEndpoint, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
83
|
+
body: body.toString(),
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
// Try to extract error details from the response body
|
|
87
|
+
const errorBody = await response.text().catch(() => '');
|
|
88
|
+
throw new PortaAuthenticationError({
|
|
89
|
+
message: `Token endpoint returned ${response.status}: ${errorBody || response.statusText}`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const data = (await response.json());
|
|
93
|
+
if (!data.access_token) {
|
|
94
|
+
throw new PortaAuthenticationError({
|
|
95
|
+
message: 'Token endpoint response missing access_token',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Cache the token with computed expiry (actual expiry minus safety margin)
|
|
99
|
+
const expiresInMs = (data.expires_in ?? DEFAULT_EXPIRES_IN_SECONDS) * 1000;
|
|
100
|
+
cachedToken = {
|
|
101
|
+
accessToken: data.access_token,
|
|
102
|
+
expiresAt: Date.now() + expiresInMs - EXPIRY_SAFETY_MARGIN_MS,
|
|
103
|
+
};
|
|
104
|
+
return data.access_token;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns true if the cached token exists and hasn't expired
|
|
108
|
+
* (accounting for the safety margin).
|
|
109
|
+
*/
|
|
110
|
+
function isTokenValid() {
|
|
111
|
+
return cachedToken !== null && Date.now() < cachedToken.expiresAt;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Gets a valid token, with concurrent request deduplication.
|
|
115
|
+
*
|
|
116
|
+
* If a valid cached token exists, returns it immediately.
|
|
117
|
+
* If another getToken() call is already fetching, waits for that result.
|
|
118
|
+
* Otherwise, initiates a new fetch.
|
|
119
|
+
*/
|
|
120
|
+
async function getTokenWithDedup() {
|
|
121
|
+
// Return cached token if still valid
|
|
122
|
+
if (isTokenValid()) {
|
|
123
|
+
return cachedToken.accessToken;
|
|
124
|
+
}
|
|
125
|
+
// Concurrent dedup: reuse the in-flight request if one exists
|
|
126
|
+
if (inFlightRequest) {
|
|
127
|
+
return inFlightRequest;
|
|
128
|
+
}
|
|
129
|
+
// Start a new token fetch and track it for dedup
|
|
130
|
+
inFlightRequest = fetchToken().finally(() => {
|
|
131
|
+
inFlightRequest = null;
|
|
132
|
+
});
|
|
133
|
+
return inFlightRequest;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
async getToken() {
|
|
137
|
+
return getTokenWithDedup();
|
|
138
|
+
},
|
|
139
|
+
async refreshToken() {
|
|
140
|
+
// Clear cached state to force a fresh fetch
|
|
141
|
+
cachedToken = null;
|
|
142
|
+
inFlightRequest = null;
|
|
143
|
+
return getTokenWithDedup();
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=client-credentials-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials-auth.js","sourceRoot":"","sources":["../../src/auth/client-credentials-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication providers for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Three auth providers are available for server-side (Node.js) transports:
|
|
5
|
+
* - {@link createTokenAuth} — Static Bearer token (simplest)
|
|
6
|
+
* - {@link createClientCredentialsAuth} — OIDC client_credentials grant (M2M)
|
|
7
|
+
* - {@link createCliAuth} — Reads Porta CLI stored credentials
|
|
8
|
+
*
|
|
9
|
+
* Browser transports use cookie-based auth and don't need auth providers.
|
|
10
|
+
*
|
|
11
|
+
* @module auth
|
|
12
|
+
*/
|
|
13
|
+
export type { AuthProvider } from './types.js';
|
|
14
|
+
export { createTokenAuth } from './token-auth.js';
|
|
15
|
+
export type { TokenAuthOptions } from './token-auth.js';
|
|
16
|
+
export { createClientCredentialsAuth } from './client-credentials-auth.js';
|
|
17
|
+
export type { ClientCredentialsAuthOptions } from './client-credentials-auth.js';
|
|
18
|
+
export { createCliAuth } from './cli-auth.js';
|
|
19
|
+
export type { CliAuthOptions, StoredCredentials } from './cli-auth.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,YAAY,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication providers for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Three auth providers are available for server-side (Node.js) transports:
|
|
5
|
+
* - {@link createTokenAuth} — Static Bearer token (simplest)
|
|
6
|
+
* - {@link createClientCredentialsAuth} — OIDC client_credentials grant (M2M)
|
|
7
|
+
* - {@link createCliAuth} — Reads Porta CLI stored credentials
|
|
8
|
+
*
|
|
9
|
+
* Browser transports use cookie-based auth and don't need auth providers.
|
|
10
|
+
*
|
|
11
|
+
* @module auth
|
|
12
|
+
*/
|
|
13
|
+
export { createTokenAuth } from './token-auth.js';
|
|
14
|
+
export { createClientCredentialsAuth } from './client-credentials-auth.js';
|
|
15
|
+
export { createCliAuth } from './cli-auth.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenAuth — static Bearer token authentication provider.
|
|
3
|
+
*
|
|
4
|
+
* The simplest auth provider: takes a pre-obtained Bearer token
|
|
5
|
+
* and returns it on every `getToken()` call. No refresh support —
|
|
6
|
+
* if the token expires, the consumer must create a new provider.
|
|
7
|
+
*
|
|
8
|
+
* Suitable for scripts, CI/CD pipelines, AI agents, and one-off
|
|
9
|
+
* automation where the token is obtained out-of-band.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createTokenAuth } from '@portaidentity/sdk';
|
|
14
|
+
*
|
|
15
|
+
* const auth = createTokenAuth({ token: 'eyJhbGciOi...' });
|
|
16
|
+
* const client = createPortaClient({ baseUrl: '...', auth });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module auth/token-auth
|
|
20
|
+
*/
|
|
21
|
+
import type { AuthProvider } from './types.js';
|
|
22
|
+
/**
|
|
23
|
+
* Options for creating a static token auth provider.
|
|
24
|
+
*/
|
|
25
|
+
export interface TokenAuthOptions {
|
|
26
|
+
/** Static Bearer token to use for all requests */
|
|
27
|
+
token: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a static token authentication provider.
|
|
31
|
+
*
|
|
32
|
+
* Returns an {@link AuthProvider} that always returns the provided token.
|
|
33
|
+
* No `refreshToken()` is defined — on 401 responses, the transport will
|
|
34
|
+
* throw a `PortaAuthenticationError` immediately.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Token auth configuration
|
|
37
|
+
* @returns An AuthProvider that returns the static token
|
|
38
|
+
*/
|
|
39
|
+
export declare function createTokenAuth(options: TokenAuthOptions): AuthProvider;
|
|
40
|
+
//# sourceMappingURL=token-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-auth.d.ts","sourceRoot":"","sources":["../../src/auth/token-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAUvE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenAuth — static Bearer token authentication provider.
|
|
3
|
+
*
|
|
4
|
+
* The simplest auth provider: takes a pre-obtained Bearer token
|
|
5
|
+
* and returns it on every `getToken()` call. No refresh support —
|
|
6
|
+
* if the token expires, the consumer must create a new provider.
|
|
7
|
+
*
|
|
8
|
+
* Suitable for scripts, CI/CD pipelines, AI agents, and one-off
|
|
9
|
+
* automation where the token is obtained out-of-band.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createTokenAuth } from '@portaidentity/sdk';
|
|
14
|
+
*
|
|
15
|
+
* const auth = createTokenAuth({ token: 'eyJhbGciOi...' });
|
|
16
|
+
* const client = createPortaClient({ baseUrl: '...', auth });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module auth/token-auth
|
|
20
|
+
*/
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Factory
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Creates a static token authentication provider.
|
|
26
|
+
*
|
|
27
|
+
* Returns an {@link AuthProvider} that always returns the provided token.
|
|
28
|
+
* No `refreshToken()` is defined — on 401 responses, the transport will
|
|
29
|
+
* throw a `PortaAuthenticationError` immediately.
|
|
30
|
+
*
|
|
31
|
+
* @param options - Token auth configuration
|
|
32
|
+
* @returns An AuthProvider that returns the static token
|
|
33
|
+
*/
|
|
34
|
+
export function createTokenAuth(options) {
|
|
35
|
+
const { token } = options;
|
|
36
|
+
return {
|
|
37
|
+
async getToken() {
|
|
38
|
+
return token;
|
|
39
|
+
},
|
|
40
|
+
// No refreshToken — 401 errors propagate immediately to the caller.
|
|
41
|
+
// The consumer must create a new TokenAuth with a fresh token.
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=token-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-auth.js","sourceRoot":"","sources":["../../src/auth/token-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAgBH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,OAAyB;IACvD,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE1B,OAAO;QACL,KAAK,CAAC,QAAQ;YACZ,OAAO,KAAK,CAAC;QACf,CAAC;QACD,oEAAoE;QACpE,+DAA+D;KAChE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication provider interface for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Auth providers handle token management for server-side transports.
|
|
5
|
+
* Three implementations are available:
|
|
6
|
+
* - TokenAuth: static token (simplest, no refresh)
|
|
7
|
+
* - ClientCredentialsAuth: OAuth2 client credentials flow
|
|
8
|
+
* - CliAuth: reads from Porta CLI credentials file
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Authentication provider that supplies access tokens to the transport.
|
|
12
|
+
*
|
|
13
|
+
* Implementations must provide `getToken()` to return a valid access token.
|
|
14
|
+
* Optionally, `refreshToken()` can be implemented to support automatic
|
|
15
|
+
* token refresh on 401 responses.
|
|
16
|
+
*/
|
|
17
|
+
export interface AuthProvider {
|
|
18
|
+
/** Returns a valid access token for API requests */
|
|
19
|
+
getToken(): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Attempts to refresh the access token.
|
|
22
|
+
* Called by NodeTransport on 401 responses for automatic retry.
|
|
23
|
+
* Returns the new access token, or throws if refresh fails.
|
|
24
|
+
* Optional — if not provided, 401 errors throw immediately.
|
|
25
|
+
*/
|
|
26
|
+
refreshToken?(): Promise<string>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5B;;;;;OAKG;IACH,YAAY,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication provider interface for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Auth providers handle token management for server-side transports.
|
|
5
|
+
* Three implementations are available:
|
|
6
|
+
* - TokenAuth: static token (simplest, no refresh)
|
|
7
|
+
* - ClientCredentialsAuth: OAuth2 client credentials flow
|
|
8
|
+
* - CliAuth: reads from Porta CLI credentials file
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @portaidentity/sdk/browser — Browser entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* Exports the browser (fetch-based) transport.
|
|
5
|
+
*
|
|
6
|
+
* @module @portaidentity/sdk/browser
|
|
7
|
+
*/
|
|
8
|
+
export { createBrowserTransport } from './transport/browser-transport.js';
|
|
9
|
+
export type { BrowserTransportOptions } from './transport/browser-transport.js';
|
|
10
|
+
export { createTokenAuth } from './auth/index.js';
|
|
11
|
+
export type { AuthProvider } from './auth/index.js';
|
|
12
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,YAAY,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAGhF,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @portaidentity/sdk/browser — Browser entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* Exports the browser (fetch-based) transport.
|
|
5
|
+
*
|
|
6
|
+
* @module @portaidentity/sdk/browser
|
|
7
|
+
*/
|
|
8
|
+
// Browser transport
|
|
9
|
+
export { createBrowserTransport } from './transport/browser-transport.js';
|
|
10
|
+
// Auth providers usable in browser
|
|
11
|
+
export { createTokenAuth } from './auth/index.js';
|
|
12
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oBAAoB;AACpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAG1E,mCAAmC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|