@atlasauth/pca-connectors 0.0.0-stage → 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.
@@ -0,0 +1,72 @@
1
+ /**
2
+ * The authorization-request side of a connector: turn a declarative {@link ProviderManifest} into a correct
3
+ * OAuth 2.0 authorize URL (with PKCE when the provider wants it), and describe how the resulting access
4
+ * token is presented on an outbound API call.
5
+ */
6
+ import { type ProviderManifest } from './manifest';
7
+ import { type ProviderRegistry } from './registry';
8
+ /** Caller-supplied PKCE material (RFC 7636). When omitted, {@link buildAuthorizeUrl} generates it. */
9
+ export interface PkceParams {
10
+ /** The high-entropy `code_verifier` (43–128 unreserved chars). */
11
+ verifier: string;
12
+ /** Challenge method. Default `'S256'`. */
13
+ method?: 'S256' | 'plain';
14
+ }
15
+ /** The PKCE values used for an authorize request; keep `verifier` to complete the code exchange. */
16
+ export interface PkceResult {
17
+ verifier: string;
18
+ challenge: string;
19
+ method: 'S256' | 'plain';
20
+ }
21
+ export interface BuildAuthorizeUrlOptions {
22
+ clientId: string;
23
+ redirectUri: string;
24
+ /** Requested scopes. Defaults to the manifest's `defaultScopes`. */
25
+ scopes?: string[];
26
+ /** CSRF `state`. A random value is generated when omitted; the value used is returned. */
27
+ state?: string;
28
+ /**
29
+ * PKCE control. `true` forces PKCE (auto-generating a verifier); an object supplies the verifier;
30
+ * `false` disables it; omitted follows the manifest's `pkce` flag.
31
+ */
32
+ pkce?: boolean | PkceParams;
33
+ /** Substitutions for `{var}` placeholders in the manifest URLs (e.g. `{ shop: 'acme' }`). */
34
+ vars?: Record<string, string>;
35
+ /** Registry to resolve `providerId` against. Defaults to the shared {@link defaultRegistry}. */
36
+ registry?: ProviderRegistry;
37
+ /** Extra authorize-request parameters, merged after the manifest's `authParams`. */
38
+ extraParams?: Record<string, string>;
39
+ }
40
+ /** A built authorize URL plus the `state` and (if used) PKCE values the caller must retain for the exchange. */
41
+ export interface AuthorizeUrl {
42
+ url: string;
43
+ state: string;
44
+ pkce?: PkceResult;
45
+ }
46
+ /** The S256 code challenge for a verifier: base64url(SHA-256(ASCII(verifier))), unpadded (RFC 7636 §4.2). */
47
+ export declare function pkceChallenge(verifier: string, method?: 'S256' | 'plain'): string;
48
+ /** Substitute `{var}` placeholders in `url`. Throws {@link ConnectorError} when a used var is not supplied. */
49
+ export declare function substituteVars(url: string, vars: Record<string, string> | undefined): string;
50
+ /**
51
+ * Build the OAuth 2.0 authorization-request URL for `providerId`. Always emits `response_type=code`,
52
+ * `client_id`, `redirect_uri`, `scope`, and `state`; adds `code_challenge` + `code_challenge_method` when
53
+ * PKCE is in effect, and merges the manifest's `authParams` then the caller's `extraParams`. Scopes are
54
+ * joined with the manifest's `scopeSeparator` (default space). Pure and synchronous.
55
+ */
56
+ export declare function buildAuthorizeUrl(providerId: string, options: BuildAuthorizeUrlOptions): AuthorizeUrl;
57
+ /** Where a manifest says an access token belongs on an outbound request. */
58
+ export type AppliedToken = {
59
+ kind: 'header';
60
+ name: string;
61
+ value: string;
62
+ } | {
63
+ kind: 'query';
64
+ name: string;
65
+ value: string;
66
+ };
67
+ /**
68
+ * Describe how `accessToken` is attached to a provider API call, per the manifest's `tokenPlacement`:
69
+ * `bearer` → `Authorization: Bearer <token>`; `header` → the custom `headerName`; `query` → the `queryParam`.
70
+ * Returns a value the caller applies to its own request; this package never performs the outbound call.
71
+ */
72
+ export declare function applyAccessToken(manifest: ProviderManifest, accessToken: string): AppliedToken;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * The authorization-request side of a connector: turn a declarative {@link ProviderManifest} into a correct
4
+ * OAuth 2.0 authorize URL (with PKCE when the provider wants it), and describe how the resulting access
5
+ * token is presented on an outbound API call.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.pkceChallenge = pkceChallenge;
9
+ exports.substituteVars = substituteVars;
10
+ exports.buildAuthorizeUrl = buildAuthorizeUrl;
11
+ exports.applyAccessToken = applyAccessToken;
12
+ const pca_1 = require("@atlasauth/pca");
13
+ const manifest_1 = require("./manifest");
14
+ const registry_1 = require("./registry");
15
+ /** 32 bytes of CSPRNG entropy, base64url (unpadded). */
16
+ function randomToken(bytes = 32) {
17
+ const b = new Uint8Array(bytes);
18
+ globalThis.crypto.getRandomValues(b);
19
+ return (0, pca_1.b64u)(b);
20
+ }
21
+ /** The S256 code challenge for a verifier: base64url(SHA-256(ASCII(verifier))), unpadded (RFC 7636 §4.2). */
22
+ function pkceChallenge(verifier, method = 'S256') {
23
+ return method === 'plain' ? verifier : (0, pca_1.b64u)((0, pca_1.sha256)((0, pca_1.utf8)(verifier)));
24
+ }
25
+ /** Substitute `{var}` placeholders in `url`. Throws {@link ConnectorError} when a used var is not supplied. */
26
+ function substituteVars(url, vars) {
27
+ return url.replace(/\{(\w+)\}/g, (_full, name) => {
28
+ const v = vars === undefined ? undefined : vars[name];
29
+ if (v === undefined)
30
+ throw new manifest_1.ConnectorError(`missing URL variable '{${name}}'`);
31
+ return v;
32
+ });
33
+ }
34
+ function encodeForm(params) {
35
+ return params.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
36
+ }
37
+ /**
38
+ * Build the OAuth 2.0 authorization-request URL for `providerId`. Always emits `response_type=code`,
39
+ * `client_id`, `redirect_uri`, `scope`, and `state`; adds `code_challenge` + `code_challenge_method` when
40
+ * PKCE is in effect, and merges the manifest's `authParams` then the caller's `extraParams`. Scopes are
41
+ * joined with the manifest's `scopeSeparator` (default space). Pure and synchronous.
42
+ */
43
+ function buildAuthorizeUrl(providerId, options) {
44
+ const registry = options.registry ?? registry_1.defaultRegistry;
45
+ const manifest = registry.require(providerId);
46
+ const scopes = options.scopes ?? manifest.defaultScopes;
47
+ const separator = manifest.scopeSeparator ?? ' ';
48
+ const state = options.state ?? randomToken();
49
+ const params = [
50
+ ['response_type', 'code'],
51
+ ['client_id', options.clientId],
52
+ ['redirect_uri', options.redirectUri],
53
+ ];
54
+ if (scopes.length > 0)
55
+ params.push(['scope', scopes.join(separator)]);
56
+ params.push(['state', state]);
57
+ // PKCE: enabled when explicitly requested, when a verifier object is passed, or (unless disabled) when
58
+ // the manifest declares it.
59
+ const wantPkce = options.pkce === false ? false : options.pkce !== undefined ? true : manifest.pkce === true;
60
+ let pkce;
61
+ if (wantPkce) {
62
+ const verifier = typeof options.pkce === 'object' ? options.pkce.verifier : randomToken();
63
+ const method = typeof options.pkce === 'object' ? options.pkce.method ?? 'S256' : 'S256';
64
+ const challenge = pkceChallenge(verifier, method);
65
+ params.push(['code_challenge', challenge], ['code_challenge_method', method]);
66
+ pkce = { verifier, challenge, method };
67
+ }
68
+ for (const [k, v] of Object.entries(manifest.authParams ?? {}))
69
+ params.push([k, v]);
70
+ for (const [k, v] of Object.entries(options.extraParams ?? {}))
71
+ params.push([k, v]);
72
+ const base = substituteVars(manifest.authorizeUrl, options.vars);
73
+ const url = `${base}${base.includes('?') ? '&' : '?'}${encodeForm(params)}`;
74
+ const result = { url, state };
75
+ if (pkce !== undefined)
76
+ result.pkce = pkce;
77
+ return result;
78
+ }
79
+ /**
80
+ * Describe how `accessToken` is attached to a provider API call, per the manifest's `tokenPlacement`:
81
+ * `bearer` → `Authorization: Bearer <token>`; `header` → the custom `headerName`; `query` → the `queryParam`.
82
+ * Returns a value the caller applies to its own request; this package never performs the outbound call.
83
+ */
84
+ function applyAccessToken(manifest, accessToken) {
85
+ switch (manifest.tokenPlacement) {
86
+ case 'bearer':
87
+ return { kind: 'header', name: 'Authorization', value: `Bearer ${accessToken}` };
88
+ case 'header': {
89
+ if (manifest.headerName === undefined)
90
+ throw new manifest_1.ConnectorError(`manifest '${manifest.id}' is header-placed but has no headerName`);
91
+ return { kind: 'header', name: manifest.headerName, value: accessToken };
92
+ }
93
+ case 'query': {
94
+ if (manifest.queryParam === undefined)
95
+ throw new manifest_1.ConnectorError(`manifest '${manifest.id}' is query-placed but has no queryParam`);
96
+ return { kind: 'query', name: manifest.queryParam, value: accessToken };
97
+ }
98
+ }
99
+ }
100
+ //# sourceMappingURL=authorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The token side of a connector: exchange an authorization code (or a refresh token) at a provider's token
3
+ * endpoint and FEED the `@atlasauth/pca-connect` vault, so every stored connection is bound to a PCA
4
+ * capability. A connection minted here is unusable until a verified Proof-Carrying Action proves authority
5
+ * over the provider and that the requested scopes are a subset of what the capability grants — that
6
+ * capability binding is the differentiator a plain token vault lacks.
7
+ *
8
+ * The vault's OWN auto-refresh (inside `getConnectionToken`) is wired from the same manifests via
9
+ * {@link manifestToProviderConfig} / {@link buildVaultProviders}, so the catalog is the single source of
10
+ * truth for both the initial grant and later refreshes.
11
+ */
12
+ import type { ProviderConfig, StoredConnection, TokenVault, VaultFetch } from '@atlasauth/pca-connect';
13
+ import { type ProviderManifest } from './manifest';
14
+ import { type ProviderRegistry } from './registry';
15
+ /** How a minted connection is stored and bound to a PCA capability in the vault. */
16
+ export interface ConnectionBinding {
17
+ vault: TokenVault;
18
+ /** b64u public key of the agent — the capability chain's LEAF holder this connection belongs to. */
19
+ agentId: string;
20
+ /** Vault connection id. Defaults to the vault's own `defaultConnectionId`. */
21
+ connectionId?: string;
22
+ authority: {
23
+ /** b64u public key the capability chain must be rooted at (the PCActn's `cap_chain[0].issuer`). */
24
+ principal: string;
25
+ /** Scopes the capability must cover. Defaults to the requested scopes (least privilege). */
26
+ scopes?: string[];
27
+ /** When set, the PCActn's signed `aud` must equal this resource-server id. */
28
+ audience?: string;
29
+ };
30
+ }
31
+ export interface ExchangeCodeArgs {
32
+ providerId: string;
33
+ clientId: string;
34
+ clientSecret?: string;
35
+ /** The authorization code returned to the redirect URI. */
36
+ code: string;
37
+ redirectUri: string;
38
+ /** The PKCE `code_verifier` used for the authorize request (required when the provider uses PKCE). */
39
+ codeVerifier?: string;
40
+ /** Scopes requested (and the least-privilege authority the connection is bound to). Defaults to the manifest's. */
41
+ scopes?: string[];
42
+ /** Injectable HTTP transport (same contract as the vault's `fetch`). */
43
+ fetch: VaultFetch;
44
+ /** How to store + capability-bind the resulting connection. */
45
+ bind: ConnectionBinding;
46
+ /** Clock, epoch ms. Defaults to `Date.now`. */
47
+ now?: number;
48
+ /** Registry to resolve `providerId` against. Defaults to {@link defaultRegistry}. */
49
+ registry?: ProviderRegistry;
50
+ /** `{var}` substitutions for the manifest token URL. */
51
+ vars?: Record<string, string>;
52
+ /** Extra static token-request form parameters. */
53
+ extraParams?: Record<string, string>;
54
+ }
55
+ export interface RefreshArgs {
56
+ providerId: string;
57
+ clientId: string;
58
+ clientSecret?: string;
59
+ /** The refresh token to present (the vault does not expose stored refresh tokens without a PCActn). */
60
+ refreshToken: string;
61
+ /** Scopes to request / re-bind. Defaults to the manifest's `defaultScopes`. */
62
+ scopes?: string[];
63
+ fetch: VaultFetch;
64
+ bind: ConnectionBinding;
65
+ now?: number;
66
+ registry?: ProviderRegistry;
67
+ vars?: Record<string, string>;
68
+ extraParams?: Record<string, string>;
69
+ }
70
+ /**
71
+ * Exchange an authorization code for tokens and store a capability-bound connection in the vault. The
72
+ * requested scopes become the connection's least-privilege authority; the connection is unusable until a
73
+ * verified PCActn proves a capability covering them.
74
+ */
75
+ export declare function exchangeCode(args: ExchangeCodeArgs): Promise<StoredConnection>;
76
+ /**
77
+ * Refresh an access token at the provider's refresh endpoint and re-store the capability-bound connection.
78
+ * Throws when the manifest declares `refresh.mode === 'none'`. Scope narrowing is sent only when the
79
+ * manifest opts in. The authority binding is preserved from `bind` (re-asserting least privilege).
80
+ */
81
+ export declare function refresh(args: RefreshArgs): Promise<StoredConnection>;
82
+ /** Per-provider client credentials used to derive a vault {@link ProviderConfig}. */
83
+ export interface ProviderCredentials {
84
+ clientId: string;
85
+ clientSecret?: string;
86
+ /** `{var}` substitutions for the refresh token endpoint (e.g. `{ shop: 'acme' }`). */
87
+ vars?: Record<string, string>;
88
+ }
89
+ /**
90
+ * Derive the `@atlasauth/pca-connect` {@link ProviderConfig} the vault uses for its OWN auto-refresh, from a
91
+ * manifest + credentials. This is how the catalog drives the vault's internal refresh: the manifest's token
92
+ * endpoint, scope-narrowing flag and extra params flow straight into the vault. Throws when the manifest
93
+ * does not support refresh.
94
+ */
95
+ export declare function manifestToProviderConfig(manifest: ProviderManifest, creds: ProviderCredentials): ProviderConfig;
96
+ /**
97
+ * Build the vault's `providers` map (provider id → {@link ProviderConfig}) from a set of configured
98
+ * providers, skipping any whose manifest cannot refresh. Pass the result to `new TokenVault({ providers })`.
99
+ */
100
+ export declare function buildVaultProviders(credsById: Record<string, ProviderCredentials>, registry?: ProviderRegistry): Record<string, ProviderConfig>;
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ /**
3
+ * The token side of a connector: exchange an authorization code (or a refresh token) at a provider's token
4
+ * endpoint and FEED the `@atlasauth/pca-connect` vault, so every stored connection is bound to a PCA
5
+ * capability. A connection minted here is unusable until a verified Proof-Carrying Action proves authority
6
+ * over the provider and that the requested scopes are a subset of what the capability grants — that
7
+ * capability binding is the differentiator a plain token vault lacks.
8
+ *
9
+ * The vault's OWN auto-refresh (inside `getConnectionToken`) is wired from the same manifests via
10
+ * {@link manifestToProviderConfig} / {@link buildVaultProviders}, so the catalog is the single source of
11
+ * truth for both the initial grant and later refreshes.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.exchangeCode = exchangeCode;
15
+ exports.refresh = refresh;
16
+ exports.manifestToProviderConfig = manifestToProviderConfig;
17
+ exports.buildVaultProviders = buildVaultProviders;
18
+ const pca_1 = require("@atlasauth/pca");
19
+ const manifest_1 = require("./manifest");
20
+ const registry_1 = require("./registry");
21
+ const authorize_1 = require("./authorize");
22
+ /** Default access-token lifetime assumed when the provider returns neither `expires_in` nor a JWT `exp`. */
23
+ const DEFAULT_TOKEN_LIFETIME_MS = 3_600_000;
24
+ /** Read own property `k` off `o` as `unknown`, without a cast. */
25
+ function prop(o, k) {
26
+ return Object.prototype.hasOwnProperty.call(o, k) ? Reflect.get(o, k) : undefined;
27
+ }
28
+ function errText(e) {
29
+ return e instanceof Error ? e.message : String(e);
30
+ }
31
+ /** Standard base64 (padded) of `s` — for HTTP Basic client authentication (RFC 6749 §2.3.1). */
32
+ function basicAuthHeader(clientId, clientSecret) {
33
+ let s = (0, pca_1.b64u)((0, pca_1.utf8)(`${clientId}:${clientSecret}`)).replace(/-/g, '+').replace(/_/g, '/');
34
+ while (s.length % 4 !== 0)
35
+ s += '=';
36
+ return `Basic ${s}`;
37
+ }
38
+ function formEncode(params) {
39
+ return Object.entries(params)
40
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
41
+ .join('&');
42
+ }
43
+ /** Parse an OAuth token-endpoint JSON body. Fails closed: a missing/empty `access_token` is a hard error. */
44
+ function parseTokenResponse(body, provider) {
45
+ if (body === null || typeof body !== 'object' || Array.isArray(body)) {
46
+ throw new manifest_1.ConnectorError(`[${provider}] token endpoint returned a non-object body`);
47
+ }
48
+ const accessToken = prop(body, 'access_token');
49
+ if (typeof accessToken !== 'string' || accessToken.length === 0) {
50
+ throw new manifest_1.ConnectorError(`[${provider}] token endpoint response has no access_token`);
51
+ }
52
+ const out = { accessToken };
53
+ const expiresIn = prop(body, 'expires_in');
54
+ if (typeof expiresIn === 'number' && Number.isFinite(expiresIn) && expiresIn > 0)
55
+ out.expiresInSecs = expiresIn;
56
+ const refreshToken = prop(body, 'refresh_token');
57
+ if (typeof refreshToken === 'string' && refreshToken.length > 0)
58
+ out.refreshToken = refreshToken;
59
+ const scope = prop(body, 'scope');
60
+ if (typeof scope === 'string' && scope.trim().length > 0)
61
+ out.scopes = scope.trim().split(/[\s,]+/);
62
+ return out;
63
+ }
64
+ /** POST a form to a token endpoint via the injectable transport and parse the response (fail-closed). */
65
+ async function postToken(manifest, tokenEndpoint, params, clientSecret, fetchImpl) {
66
+ const headers = {
67
+ 'content-type': 'application/x-www-form-urlencoded',
68
+ accept: 'application/json',
69
+ };
70
+ const body = { ...params };
71
+ if (manifest.clientAuth === 'basic') {
72
+ // Client credentials move to the Authorization header; they must not also appear in the body.
73
+ if (clientSecret === undefined)
74
+ throw new manifest_1.ConnectorError(`[${manifest.id}] clientAuth 'basic' requires a clientSecret`);
75
+ const clientId = body['client_id'];
76
+ if (clientId === undefined)
77
+ throw new manifest_1.ConnectorError(`[${manifest.id}] missing client_id for basic auth`);
78
+ headers['authorization'] = basicAuthHeader(clientId, clientSecret);
79
+ delete body['client_id'];
80
+ delete body['client_secret'];
81
+ }
82
+ let res;
83
+ try {
84
+ res = await fetchImpl(tokenEndpoint, { method: 'POST', headers, body: formEncode(body) });
85
+ }
86
+ catch (e) {
87
+ throw new manifest_1.ConnectorError(`[${manifest.id}] token transport error: ${errText(e)}`);
88
+ }
89
+ if (!res.ok) {
90
+ let detail = '';
91
+ try {
92
+ detail = (await res.text()).slice(0, 256);
93
+ }
94
+ catch {
95
+ detail = '<unreadable body>';
96
+ }
97
+ throw new manifest_1.ConnectorError(`[${manifest.id}] token endpoint ${res.status}: ${detail}`);
98
+ }
99
+ let json;
100
+ try {
101
+ json = await res.json();
102
+ }
103
+ catch (e) {
104
+ throw new manifest_1.ConnectorError(`[${manifest.id}] unparseable token JSON: ${errText(e)}`);
105
+ }
106
+ return parseTokenResponse(json, manifest.id);
107
+ }
108
+ /** Store the token result in the vault, bound to the PCA capability authority. */
109
+ async function storeConnection(manifest, parsed, requested, bind, now, priorRefreshToken) {
110
+ const expiresAt = parsed.expiresInSecs !== undefined ? now + parsed.expiresInSecs * 1000 : now + DEFAULT_TOKEN_LIFETIME_MS;
111
+ // Scopes the stored token actually carries: the provider's echo wins; else the requested set.
112
+ const granted = parsed.scopes ?? requested;
113
+ // Token rotation: keep the prior refresh token unless the provider issued a new one.
114
+ const refreshToken = parsed.refreshToken ?? priorRefreshToken;
115
+ return bind.vault.putConnection({
116
+ agentId: bind.agentId,
117
+ provider: manifest.id,
118
+ accessToken: parsed.accessToken,
119
+ expiresAt,
120
+ scopes: granted,
121
+ authority: {
122
+ principal: bind.authority.principal,
123
+ scopes: bind.authority.scopes ?? requested,
124
+ ...(bind.authority.audience !== undefined ? { audience: bind.authority.audience } : {}),
125
+ },
126
+ ...(bind.connectionId !== undefined ? { connectionId: bind.connectionId } : {}),
127
+ ...(refreshToken !== undefined ? { refreshToken } : {}),
128
+ });
129
+ }
130
+ /**
131
+ * Exchange an authorization code for tokens and store a capability-bound connection in the vault. The
132
+ * requested scopes become the connection's least-privilege authority; the connection is unusable until a
133
+ * verified PCActn proves a capability covering them.
134
+ */
135
+ async function exchangeCode(args) {
136
+ const registry = args.registry ?? registry_1.defaultRegistry;
137
+ const manifest = registry.require(args.providerId);
138
+ const now = args.now ?? Date.now();
139
+ const requested = args.scopes ?? manifest.defaultScopes;
140
+ if (manifest.pkce === true && args.codeVerifier === undefined) {
141
+ throw new manifest_1.ConnectorError(`[${manifest.id}] provider uses PKCE; a codeVerifier is required to exchange the code`);
142
+ }
143
+ const params = {
144
+ grant_type: 'authorization_code',
145
+ code: args.code,
146
+ redirect_uri: args.redirectUri,
147
+ client_id: args.clientId,
148
+ ...(args.clientSecret !== undefined ? { client_secret: args.clientSecret } : {}),
149
+ ...(args.codeVerifier !== undefined ? { code_verifier: args.codeVerifier } : {}),
150
+ ...(args.extraParams ?? {}),
151
+ };
152
+ const tokenEndpoint = (0, authorize_1.substituteVars)(manifest.tokenUrl, args.vars);
153
+ const parsed = await postToken(manifest, tokenEndpoint, params, args.clientSecret, args.fetch);
154
+ return storeConnection(manifest, parsed, requested, args.bind, now);
155
+ }
156
+ /**
157
+ * Refresh an access token at the provider's refresh endpoint and re-store the capability-bound connection.
158
+ * Throws when the manifest declares `refresh.mode === 'none'`. Scope narrowing is sent only when the
159
+ * manifest opts in. The authority binding is preserved from `bind` (re-asserting least privilege).
160
+ */
161
+ async function refresh(args) {
162
+ const registry = args.registry ?? registry_1.defaultRegistry;
163
+ const manifest = registry.require(args.providerId);
164
+ if (manifest.refresh.mode === 'none') {
165
+ throw new manifest_1.ConnectorError(`[${manifest.id}] provider does not support token refresh`);
166
+ }
167
+ const now = args.now ?? Date.now();
168
+ const requested = args.scopes ?? manifest.defaultScopes;
169
+ const params = {
170
+ grant_type: 'refresh_token',
171
+ refresh_token: args.refreshToken,
172
+ client_id: args.clientId,
173
+ ...(args.clientSecret !== undefined ? { client_secret: args.clientSecret } : {}),
174
+ ...(manifest.refresh.extraParams ?? {}),
175
+ ...(args.extraParams ?? {}),
176
+ };
177
+ if (manifest.refresh.supportsScopeNarrowing === true && requested.length > 0) {
178
+ params['scope'] = requested.join(manifest.scopeSeparator ?? ' ');
179
+ }
180
+ const tokenEndpoint = (0, authorize_1.substituteVars)(manifest.refresh.tokenEndpoint ?? manifest.tokenUrl, args.vars);
181
+ const parsed = await postToken(manifest, tokenEndpoint, params, args.clientSecret, args.fetch);
182
+ return storeConnection(manifest, parsed, requested, args.bind, now, args.refreshToken);
183
+ }
184
+ /**
185
+ * Derive the `@atlasauth/pca-connect` {@link ProviderConfig} the vault uses for its OWN auto-refresh, from a
186
+ * manifest + credentials. This is how the catalog drives the vault's internal refresh: the manifest's token
187
+ * endpoint, scope-narrowing flag and extra params flow straight into the vault. Throws when the manifest
188
+ * does not support refresh.
189
+ */
190
+ function manifestToProviderConfig(manifest, creds) {
191
+ if (manifest.refresh.mode === 'none') {
192
+ throw new manifest_1.ConnectorError(`[${manifest.id}] provider does not support token refresh; no ProviderConfig`);
193
+ }
194
+ const config = {
195
+ tokenEndpoint: (0, authorize_1.substituteVars)(manifest.refresh.tokenEndpoint ?? manifest.tokenUrl, creds.vars),
196
+ clientId: creds.clientId,
197
+ };
198
+ if (creds.clientSecret !== undefined)
199
+ config.clientSecret = creds.clientSecret;
200
+ if (manifest.refresh.supportsScopeNarrowing !== undefined)
201
+ config.supportsScopeNarrowing = manifest.refresh.supportsScopeNarrowing;
202
+ if (manifest.refresh.extraParams !== undefined)
203
+ config.extraParams = { ...manifest.refresh.extraParams };
204
+ return config;
205
+ }
206
+ /**
207
+ * Build the vault's `providers` map (provider id → {@link ProviderConfig}) from a set of configured
208
+ * providers, skipping any whose manifest cannot refresh. Pass the result to `new TokenVault({ providers })`.
209
+ */
210
+ function buildVaultProviders(credsById, registry = registry_1.defaultRegistry) {
211
+ const out = {};
212
+ for (const [id, creds] of Object.entries(credsById)) {
213
+ const manifest = registry.require(id);
214
+ if (manifest.refresh.mode === 'none')
215
+ continue;
216
+ out[id] = manifestToProviderConfig(manifest, creds);
217
+ }
218
+ return out;
219
+ }
220
+ //# sourceMappingURL=exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchange.js","sourceRoot":"","sources":["../src/exchange.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@atlasauth/pca-connectors` — the connector catalog for Proof-Carrying Authority.
3
+ *
4
+ * A declarative registry of outbound SaaS providers (Google, GitHub, Slack, …) as data manifests, plus the
5
+ * authorize-URL / code-exchange / refresh helpers that feed the `@atlasauth/pca-connect` token vault. Wiring
6
+ * a new outbound tool is a manifest edit, and EVERY connection minted here is bound to a PCA capability —
7
+ * so every outbound token a tool call presents is a proof-carrying, least-privilege capability, not an
8
+ * ambient secret. That capability binding is the property Composio / Descope / Auth0 Token Vault lack.
9
+ *
10
+ * This is the CODE layer; a hosted consent UI is a separate product piece built on top of it.
11
+ */
12
+ export { type TokenPlacement, type RefreshMode, type ClientAuthMethod, type RefreshSpec, type ProviderManifest, type ManifestValidation, ConnectorError, ManifestValidationError, UnknownProviderError, validateManifest, assertManifest, } from './manifest';
13
+ export { ProviderRegistry, createDefaultRegistry, defaultRegistry, registerProvider, getProvider, listProviders, } from './registry';
14
+ export { type PkceParams, type PkceResult, type BuildAuthorizeUrlOptions, type AuthorizeUrl, type AppliedToken, buildAuthorizeUrl, pkceChallenge, substituteVars, applyAccessToken, } from './authorize';
15
+ export { type ConnectionBinding, type ExchangeCodeArgs, type RefreshArgs, type ProviderCredentials, exchangeCode, refresh, manifestToProviderConfig, buildVaultProviders, } from './exchange';
16
+ export * as providers from './providers';
17
+ export { type ConnectionToken, type StoredConnection, type ProviderConfig, type VaultFetch, type VaultHttpRequest, type VaultHttpResponse, TokenVault, InMemoryConnectionStore, oauthScopeCaveat, grantedOAuthScopes, NotAuthorizedError, ScopeExceededError, ExpiredNoRefreshError, RefreshFailedError, UnknownConnectionError, VaultError, } from '@atlasauth/pca-connect';
package/dist/index.js ADDED
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * `@atlasauth/pca-connectors` — the connector catalog for Proof-Carrying Authority.
4
+ *
5
+ * A declarative registry of outbound SaaS providers (Google, GitHub, Slack, …) as data manifests, plus the
6
+ * authorize-URL / code-exchange / refresh helpers that feed the `@atlasauth/pca-connect` token vault. Wiring
7
+ * a new outbound tool is a manifest edit, and EVERY connection minted here is bound to a PCA capability —
8
+ * so every outbound token a tool call presents is a proof-carrying, least-privilege capability, not an
9
+ * ambient secret. That capability binding is the property Composio / Descope / Auth0 Token Vault lack.
10
+ *
11
+ * This is the CODE layer; a hosted consent UI is a separate product piece built on top of it.
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.VaultError = exports.UnknownConnectionError = exports.RefreshFailedError = exports.ExpiredNoRefreshError = exports.ScopeExceededError = exports.NotAuthorizedError = exports.grantedOAuthScopes = exports.oauthScopeCaveat = exports.InMemoryConnectionStore = exports.TokenVault = exports.providers = exports.buildVaultProviders = exports.manifestToProviderConfig = exports.refresh = exports.exchangeCode = exports.applyAccessToken = exports.substituteVars = exports.pkceChallenge = exports.buildAuthorizeUrl = exports.listProviders = exports.getProvider = exports.registerProvider = exports.defaultRegistry = exports.createDefaultRegistry = exports.ProviderRegistry = exports.assertManifest = exports.validateManifest = exports.UnknownProviderError = exports.ManifestValidationError = exports.ConnectorError = void 0;
48
+ var manifest_1 = require("./manifest");
49
+ Object.defineProperty(exports, "ConnectorError", { enumerable: true, get: function () { return manifest_1.ConnectorError; } });
50
+ Object.defineProperty(exports, "ManifestValidationError", { enumerable: true, get: function () { return manifest_1.ManifestValidationError; } });
51
+ Object.defineProperty(exports, "UnknownProviderError", { enumerable: true, get: function () { return manifest_1.UnknownProviderError; } });
52
+ Object.defineProperty(exports, "validateManifest", { enumerable: true, get: function () { return manifest_1.validateManifest; } });
53
+ Object.defineProperty(exports, "assertManifest", { enumerable: true, get: function () { return manifest_1.assertManifest; } });
54
+ var registry_1 = require("./registry");
55
+ Object.defineProperty(exports, "ProviderRegistry", { enumerable: true, get: function () { return registry_1.ProviderRegistry; } });
56
+ Object.defineProperty(exports, "createDefaultRegistry", { enumerable: true, get: function () { return registry_1.createDefaultRegistry; } });
57
+ Object.defineProperty(exports, "defaultRegistry", { enumerable: true, get: function () { return registry_1.defaultRegistry; } });
58
+ Object.defineProperty(exports, "registerProvider", { enumerable: true, get: function () { return registry_1.registerProvider; } });
59
+ Object.defineProperty(exports, "getProvider", { enumerable: true, get: function () { return registry_1.getProvider; } });
60
+ Object.defineProperty(exports, "listProviders", { enumerable: true, get: function () { return registry_1.listProviders; } });
61
+ var authorize_1 = require("./authorize");
62
+ Object.defineProperty(exports, "buildAuthorizeUrl", { enumerable: true, get: function () { return authorize_1.buildAuthorizeUrl; } });
63
+ Object.defineProperty(exports, "pkceChallenge", { enumerable: true, get: function () { return authorize_1.pkceChallenge; } });
64
+ Object.defineProperty(exports, "substituteVars", { enumerable: true, get: function () { return authorize_1.substituteVars; } });
65
+ Object.defineProperty(exports, "applyAccessToken", { enumerable: true, get: function () { return authorize_1.applyAccessToken; } });
66
+ var exchange_1 = require("./exchange");
67
+ Object.defineProperty(exports, "exchangeCode", { enumerable: true, get: function () { return exchange_1.exchangeCode; } });
68
+ Object.defineProperty(exports, "refresh", { enumerable: true, get: function () { return exchange_1.refresh; } });
69
+ Object.defineProperty(exports, "manifestToProviderConfig", { enumerable: true, get: function () { return exchange_1.manifestToProviderConfig; } });
70
+ Object.defineProperty(exports, "buildVaultProviders", { enumerable: true, get: function () { return exchange_1.buildVaultProviders; } });
71
+ exports.providers = __importStar(require("./providers"));
72
+ // Re-export the vault primitives this catalog is built on, so a consumer can assemble the whole outbound
73
+ // surface — manifests + vault + capability binding — from one import.
74
+ var pca_connect_1 = require("@atlasauth/pca-connect");
75
+ Object.defineProperty(exports, "TokenVault", { enumerable: true, get: function () { return pca_connect_1.TokenVault; } });
76
+ Object.defineProperty(exports, "InMemoryConnectionStore", { enumerable: true, get: function () { return pca_connect_1.InMemoryConnectionStore; } });
77
+ Object.defineProperty(exports, "oauthScopeCaveat", { enumerable: true, get: function () { return pca_connect_1.oauthScopeCaveat; } });
78
+ Object.defineProperty(exports, "grantedOAuthScopes", { enumerable: true, get: function () { return pca_connect_1.grantedOAuthScopes; } });
79
+ Object.defineProperty(exports, "NotAuthorizedError", { enumerable: true, get: function () { return pca_connect_1.NotAuthorizedError; } });
80
+ Object.defineProperty(exports, "ScopeExceededError", { enumerable: true, get: function () { return pca_connect_1.ScopeExceededError; } });
81
+ Object.defineProperty(exports, "ExpiredNoRefreshError", { enumerable: true, get: function () { return pca_connect_1.ExpiredNoRefreshError; } });
82
+ Object.defineProperty(exports, "RefreshFailedError", { enumerable: true, get: function () { return pca_connect_1.RefreshFailedError; } });
83
+ Object.defineProperty(exports, "UnknownConnectionError", { enumerable: true, get: function () { return pca_connect_1.UnknownConnectionError; } });
84
+ Object.defineProperty(exports, "VaultError", { enumerable: true, get: function () { return pca_connect_1.VaultError; } });
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAYoB;AALlB,0GAAA,cAAc,OAAA;AACd,mHAAA,uBAAuB,OAAA;AACvB,gHAAA,oBAAoB,OAAA;AACpB,4GAAA,gBAAgB,OAAA;AAChB,0GAAA,cAAc,OAAA;AAGhB,uCAOoB;AANlB,4GAAA,gBAAgB,OAAA;AAChB,iHAAA,qBAAqB,OAAA;AACrB,2GAAA,eAAe,OAAA;AACf,4GAAA,gBAAgB,OAAA;AAChB,uGAAA,WAAW,OAAA;AACX,yGAAA,aAAa,OAAA;AAGf,yCAUqB;AAJnB,8GAAA,iBAAiB,OAAA;AACjB,0GAAA,aAAa,OAAA;AACb,2GAAA,cAAc,OAAA;AACd,6GAAA,gBAAgB,OAAA;AAGlB,uCASoB;AAJlB,wGAAA,YAAY,OAAA;AACZ,mGAAA,OAAO,OAAA;AACP,oHAAA,wBAAwB,OAAA;AACxB,+GAAA,mBAAmB,OAAA;AAGrB,yDAAyC;AAEzC,yGAAyG;AACzG,sEAAsE;AACtE,sDAiBgC;AAV9B,yGAAA,UAAU,OAAA;AACV,sHAAA,uBAAuB,OAAA;AACvB,+GAAA,gBAAgB,OAAA;AAChB,iHAAA,kBAAkB,OAAA;AAClB,iHAAA,kBAAkB,OAAA;AAClB,iHAAA,kBAAkB,OAAA;AAClB,oHAAA,qBAAqB,OAAA;AACrB,iHAAA,kBAAkB,OAAA;AAClB,qHAAA,sBAAsB,OAAA;AACtB,yGAAA,UAAU,OAAA"}