@atlasauth/js 0.24.0 → 0.26.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/CHANGELOG.md +16 -1
- package/dist/app-launcher.d.ts +5 -0
- package/dist/app-launcher.js +8 -0
- package/dist/app-launcher.js.map +1 -1
- package/dist/authorized-apps.d.ts +42 -0
- package/dist/authorized-apps.js +41 -0
- package/dist/authorized-apps.js.map +1 -0
- package/dist/ciba.d.ts +38 -0
- package/dist/ciba.js +53 -0
- package/dist/ciba.js.map +1 -0
- package/dist/connections.d.ts +121 -3
- package/dist/connections.js +72 -8
- package/dist/connections.js.map +1 -1
- package/dist/connector-directory.d.ts +29 -0
- package/dist/connector-directory.js +24 -0
- package/dist/connector-directory.js.map +1 -0
- package/dist/fapi.d.ts +27 -1
- package/dist/fapi.js +25 -2
- package/dist/fapi.js.map +1 -1
- package/dist/iga.d.ts +118 -0
- package/dist/iga.js +60 -0
- package/dist/iga.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/passkey.d.ts +12 -0
- package/dist/passkey.js +30 -1
- package/dist/passkey.js.map +1 -1
- package/dist/referral.js +3 -0
- package/dist/referral.js.map +1 -1
- package/dist/resource-sharing.d.ts +70 -0
- package/dist/resource-sharing.js +32 -0
- package/dist/resource-sharing.js.map +1 -0
- package/dist/srp.d.ts +55 -0
- package/dist/srp.js +120 -0
- package/dist/srp.js.map +1 -0
- package/dist/uma.d.ts +86 -0
- package/dist/uma.js +73 -0
- package/dist/uma.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# @atlasauth/js changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.26.0 — 2026-10-28
|
|
4
|
+
|
|
5
|
+
- CIBA approvals and PIN (`listCibaRequests`, `decideCibaRequest`, `getCibaPin`, `setCibaPin`, `clearCibaPin`)
|
|
6
|
+
- Cross-device magic link (`prepareFactor(..., { crossDevice: true })`, `previewCrossDeviceLink`, `confirmCrossDeviceLink`)
|
|
7
|
+
- Passkey hints, conditional create and `getClientCapabilities`
|
|
8
|
+
- Resource sharing client and connector directory facets
|
|
9
|
+
|
|
10
|
+
## 0.25.0 — 2026-10-27
|
|
11
|
+
|
|
12
|
+
- `signInWithSrp` and `srpClientStart`: SRP-6a password sign-in (RFC 5054, 3072-bit group, SHA-256), so the password never leaves the browser.
|
|
13
|
+
- `listAuthorizedApps`, `disconnectAuthorizedApp` and `revokeAppGrant`: the apps a user authorized, with the OpenID Grant Management grants each holds.
|
|
14
|
+
- Identity governance for the signed-in user: `listAccessCatalog`, `requestAccess`, `listMyAccess`, `listMyAccessRequests`, `getAccessRequest`, `cancelAccessRequest`, `listPendingApprovals`, `decideAccessRequest`, `listAccessReviews`, `decideAccessReview`, `listAccessDelegations`, `delegateApprovals` and `endDelegation`.
|
|
15
|
+
- Connections: `revokeMyConnection` and `revokeOrganizationConnection` return `provider_revoked` (true, false or `'unsupported'`), `provider_status`, `provider_error` and `local_cleared`; `AppConnection.last_error` carries the provider's code and HTTP status and `refresh_failures`.
|
|
16
|
+
- Connections: `setOrganizationConnectionCredentials` takes every credential field (bearer token, basic username and password, custom header value, HMAC secret, signing key, OAuth 1.0a keys), `expiresAt` and `config`; `AppConnection.kind` lists the new kinds and carries `secret_expires_at`. There is still no call that reads a credential back.
|
|
17
|
+
- Connections: `connectMyConnection`, `connectOrganizationConnection`, `revokeOrganizationConnection`, `listOrganizationOAuthClients`, `setOrganizationOAuthClient`, `deleteOrganizationOAuthClient`; `AppConnection` carries `environment`, `external_id`, `host_params`, `scopes`, `metadata` and `last_error`, and its status adds `revoked` and `error`.
|
|
18
|
+
- User-managed access for resource owners: `listUmaResources`, `shareUmaResource`, `unshareUmaResource`, `listUmaAccessRequests` and `decideUmaAccessRequest`, with a typed `UmaError`, plus `umaClaimsUrl` and `parseUmaClaimsRedirect` for the claims-gathering redirect.
|
|
4
19
|
|
|
5
20
|
## 0.24.0 — 2026-10-26
|
|
6
21
|
|
package/dist/app-launcher.d.ts
CHANGED
|
@@ -9,3 +9,8 @@ export interface LauncherApp {
|
|
|
9
9
|
}
|
|
10
10
|
/** The apps the signed-in user may launch. Rejects when nobody is signed in. */
|
|
11
11
|
export declare function listLauncherApps(client: FapiClient): Promise<LauncherApp[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Where to send the browser to sign out of Atlas and every SAML app it signed in to (single logout).
|
|
14
|
+
* Navigate to it; apps that publish a logout endpoint are told, then a signed-out page is shown.
|
|
15
|
+
*/
|
|
16
|
+
export declare function samlLogoutUrl(client: FapiClient): string;
|
package/dist/app-launcher.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.listLauncherApps = listLauncherApps;
|
|
4
|
+
exports.samlLogoutUrl = samlLogoutUrl;
|
|
4
5
|
/** The apps the signed-in user may launch. Rejects when nobody is signed in. */
|
|
5
6
|
async function listLauncherApps(client) {
|
|
6
7
|
const res = await client.request('/v1/saml/idp/apps', { method: 'GET' });
|
|
@@ -9,4 +10,11 @@ async function listLauncherApps(client) {
|
|
|
9
10
|
}
|
|
10
11
|
return res.data.data.map((a) => ({ id: a.id, name: a.name, presetId: a.preset_id, launchUrl: a.launch_url }));
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Where to send the browser to sign out of Atlas and every SAML app it signed in to (single logout).
|
|
15
|
+
* Navigate to it; apps that publish a logout endpoint are told, then a signed-out page is shown.
|
|
16
|
+
*/
|
|
17
|
+
function samlLogoutUrl(client) {
|
|
18
|
+
return client.urlFor(`/v1/saml/idp/slo/start?pk=${encodeURIComponent(client.publishableKey)}`);
|
|
19
|
+
}
|
|
12
20
|
//# sourceMappingURL=app-launcher.js.map
|
package/dist/app-launcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-launcher.js","sourceRoot":"","sources":["../src/app-launcher.ts"],"names":[],"mappings":";;AAmBA,4CAMC;
|
|
1
|
+
{"version":3,"file":"app-launcher.js","sourceRoot":"","sources":["../src/app-launcher.ts"],"names":[],"mappings":";;AAmBA,4CAMC;AAMD,sCAEC;AAfD,gFAAgF;AACzE,KAAK,UAAU,gBAAgB,CAAC,MAAkB;IACvD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAA8B,mBAAmB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtG,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,2BAA2B,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAChH,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,MAAkB;IAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,6BAA6B,kBAAkB,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AACjG,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { FapiClient } from './fapi';
|
|
2
|
+
/**
|
|
3
|
+
* The signed-in user's authorized apps: the third-party OAuth clients they signed
|
|
4
|
+
* in to with this application, and the grants (OpenID Grant Management `grant_id`s)
|
|
5
|
+
* each holds. Cookie-authenticated through the {@link FapiClient}
|
|
6
|
+
* (`/v1/client/me/oauth_grants`, `/v1/client/me/managed_grants`).
|
|
7
|
+
*/
|
|
8
|
+
/** One grant an app holds for the user; withdrawing it ends every token issued under it. */
|
|
9
|
+
export interface AppGrant {
|
|
10
|
+
id: string;
|
|
11
|
+
scopes: string[];
|
|
12
|
+
/** The API the grant covers, when it is for one. */
|
|
13
|
+
resource: string | null;
|
|
14
|
+
created_at: number;
|
|
15
|
+
updated_at: number;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthorizedApp {
|
|
18
|
+
object: 'oauth_grant';
|
|
19
|
+
/** The remembered consent's id; pass it to {@link disconnectAuthorizedApp}. */
|
|
20
|
+
id: string;
|
|
21
|
+
client_id: string | null;
|
|
22
|
+
name: string;
|
|
23
|
+
logo_url: string | null;
|
|
24
|
+
first_party: boolean;
|
|
25
|
+
scopes: string[];
|
|
26
|
+
grants: AppGrant[];
|
|
27
|
+
created_at: number;
|
|
28
|
+
}
|
|
29
|
+
/** A refused request; `code` is the server's stable error code. */
|
|
30
|
+
export declare class AuthorizedAppsError extends Error {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
readonly code: string;
|
|
33
|
+
constructor(status: number, code: string, message: string);
|
|
34
|
+
}
|
|
35
|
+
/** The apps this user authorized, each with the grants it holds. */
|
|
36
|
+
export declare function listAuthorizedApps(client: FapiClient): Promise<AuthorizedApp[]>;
|
|
37
|
+
/** Forget an app entirely: its consent, every grant and every live token. */
|
|
38
|
+
export declare function disconnectAuthorizedApp(client: FapiClient, consentId: string): Promise<void>;
|
|
39
|
+
/** Withdraw one grant of an app, leaving its other grants alone. Every token issued under it ends at once. */
|
|
40
|
+
export declare function revokeAppGrant(client: FapiClient, grantId: string): Promise<{
|
|
41
|
+
tokensEnded: number;
|
|
42
|
+
}>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthorizedAppsError = void 0;
|
|
4
|
+
exports.listAuthorizedApps = listAuthorizedApps;
|
|
5
|
+
exports.disconnectAuthorizedApp = disconnectAuthorizedApp;
|
|
6
|
+
exports.revokeAppGrant = revokeAppGrant;
|
|
7
|
+
/** A refused request; `code` is the server's stable error code. */
|
|
8
|
+
class AuthorizedAppsError extends Error {
|
|
9
|
+
status;
|
|
10
|
+
code;
|
|
11
|
+
constructor(status, code, message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'AuthorizedAppsError';
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.code = code;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.AuthorizedAppsError = AuthorizedAppsError;
|
|
19
|
+
async function call(client, path, init) {
|
|
20
|
+
const res = await client.request(path, init);
|
|
21
|
+
if (!res.ok || !res.data) {
|
|
22
|
+
const first = res.errors[0];
|
|
23
|
+
throw new AuthorizedAppsError(res.status, first?.code ?? 'UNKNOWN', first?.message ?? 'The request failed.');
|
|
24
|
+
}
|
|
25
|
+
return res.data;
|
|
26
|
+
}
|
|
27
|
+
/** The apps this user authorized, each with the grants it holds. */
|
|
28
|
+
async function listAuthorizedApps(client) {
|
|
29
|
+
const body = await call(client, '/v1/client/me/oauth_grants', { method: 'GET' });
|
|
30
|
+
return (body.data ?? []).map((app) => ({ ...app, grants: app.grants ?? [] }));
|
|
31
|
+
}
|
|
32
|
+
/** Forget an app entirely: its consent, every grant and every live token. */
|
|
33
|
+
async function disconnectAuthorizedApp(client, consentId) {
|
|
34
|
+
await call(client, `/v1/client/me/oauth_grants/${encodeURIComponent(consentId)}`, { method: 'DELETE' });
|
|
35
|
+
}
|
|
36
|
+
/** Withdraw one grant of an app, leaving its other grants alone. Every token issued under it ends at once. */
|
|
37
|
+
async function revokeAppGrant(client, grantId) {
|
|
38
|
+
const body = await call(client, `/v1/client/me/managed_grants/${encodeURIComponent(grantId)}`, { method: 'DELETE' });
|
|
39
|
+
return { tokensEnded: body.tokens_ended ?? 0 };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=authorized-apps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorized-apps.js","sourceRoot":"","sources":["../src/authorized-apps.ts"],"names":[],"mappings":";;;AAsDA,gDAGC;AAGD,0DAEC;AAGD,wCAGC;AApCD,mEAAmE;AACnE,MAAa,mBAAoB,SAAQ,KAAK;IACnC,MAAM,CAAS;IACf,IAAI,CAAS;IACtB,YAAY,MAAc,EAAE,IAAY,EAAE,OAAe;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AATD,kDASC;AAED,KAAK,UAAU,IAAI,CAAI,MAAkB,EAAE,IAAY,EAAE,IAAiB;IACxE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,KAAK,EAAE,OAAO,IAAI,qBAAqB,CAAC,CAAC;IAC/G,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,oEAAoE;AAC7D,KAAK,UAAU,kBAAkB,CAAC,MAAkB;IACzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAA6B,MAAM,EAAE,4BAA4B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7G,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,6EAA6E;AACtE,KAAK,UAAU,uBAAuB,CAAC,MAAkB,EAAE,SAAiB;IACjF,MAAM,IAAI,CAAC,MAAM,EAAE,8BAA8B,kBAAkB,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1G,CAAC;AAED,8GAA8G;AACvG,KAAK,UAAU,cAAc,CAAC,MAAkB,EAAE,OAAe;IACtE,MAAM,IAAI,GAAG,MAAM,IAAI,CAA4B,MAAM,EAAE,gCAAgC,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChJ,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC,EAAE,CAAC;AACjD,CAAC"}
|
package/dist/ciba.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FapiClient } from './fapi';
|
|
2
|
+
/**
|
|
3
|
+
* CIBA self-service for the signed-in user: the backchannel requests waiting for their decision, and the
|
|
4
|
+
* optional CIBA PIN apps must send as the `user_code`. Cookie-authenticated through the {@link FapiClient}
|
|
5
|
+
* (`/v1/client/me/backchannel_requests`, `/v1/client/me/ciba_pin`); a bearer token is refused by the server.
|
|
6
|
+
*/
|
|
7
|
+
export interface CibaRequest {
|
|
8
|
+
id: string;
|
|
9
|
+
client_name: string;
|
|
10
|
+
scope: string[];
|
|
11
|
+
binding_message: string | null;
|
|
12
|
+
created_at: number;
|
|
13
|
+
expires_at: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CibaPinStatus {
|
|
16
|
+
set: boolean;
|
|
17
|
+
updated_at: number | null;
|
|
18
|
+
/** Some app on this instance can start CIBA requests, so showing the PIN form is worthwhile. */
|
|
19
|
+
available: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare class CibaError extends Error {
|
|
22
|
+
readonly status: number;
|
|
23
|
+
readonly code: string;
|
|
24
|
+
constructor(status: number, code: string, message: string);
|
|
25
|
+
}
|
|
26
|
+
/** Requests from apps waiting for this user to approve or deny. */
|
|
27
|
+
export declare function listCibaRequests(client: FapiClient): Promise<CibaRequest[]>;
|
|
28
|
+
/** Approve or deny one request. */
|
|
29
|
+
export declare function decideCibaRequest(client: FapiClient, id: string, decision: 'approve' | 'deny'): Promise<'approved' | 'denied'>;
|
|
30
|
+
export declare function getCibaPin(client: FapiClient): Promise<CibaPinStatus>;
|
|
31
|
+
/** Set or change the PIN (6 to 12 digits). Needs the current password and a recent sign-in. */
|
|
32
|
+
export declare function setCibaPin(client: FapiClient, input: {
|
|
33
|
+
pin: string;
|
|
34
|
+
currentPassword?: string;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
export declare function clearCibaPin(client: FapiClient, input?: {
|
|
37
|
+
currentPassword?: string;
|
|
38
|
+
}): Promise<void>;
|
package/dist/ciba.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CibaError = void 0;
|
|
4
|
+
exports.listCibaRequests = listCibaRequests;
|
|
5
|
+
exports.decideCibaRequest = decideCibaRequest;
|
|
6
|
+
exports.getCibaPin = getCibaPin;
|
|
7
|
+
exports.setCibaPin = setCibaPin;
|
|
8
|
+
exports.clearCibaPin = clearCibaPin;
|
|
9
|
+
class CibaError extends Error {
|
|
10
|
+
status;
|
|
11
|
+
code;
|
|
12
|
+
constructor(status, code, message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'CibaError';
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.CibaError = CibaError;
|
|
20
|
+
async function call(client, path, init) {
|
|
21
|
+
const res = await client.request(path, init);
|
|
22
|
+
if (!res.ok || !res.data) {
|
|
23
|
+
const first = res.errors[0];
|
|
24
|
+
throw new CibaError(res.status, first?.code ?? 'UNKNOWN', first?.message ?? 'The request failed.');
|
|
25
|
+
}
|
|
26
|
+
return res.data;
|
|
27
|
+
}
|
|
28
|
+
const json = (method, body) => ({
|
|
29
|
+
method,
|
|
30
|
+
...(body === undefined ? {} : { headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }),
|
|
31
|
+
});
|
|
32
|
+
/** Requests from apps waiting for this user to approve or deny. */
|
|
33
|
+
async function listCibaRequests(client) {
|
|
34
|
+
const body = await call(client, '/v1/client/me/backchannel_requests', json('GET'));
|
|
35
|
+
return body.data ?? [];
|
|
36
|
+
}
|
|
37
|
+
/** Approve or deny one request. */
|
|
38
|
+
async function decideCibaRequest(client, id, decision) {
|
|
39
|
+
const body = await call(client, `/v1/client/me/backchannel_requests/${encodeURIComponent(id)}`, json('POST', { decision }));
|
|
40
|
+
return body.status;
|
|
41
|
+
}
|
|
42
|
+
async function getCibaPin(client) {
|
|
43
|
+
const body = await call(client, '/v1/client/me/ciba_pin', json('GET'));
|
|
44
|
+
return { set: body.set, updated_at: body.updated_at ?? null, available: body.available ?? false };
|
|
45
|
+
}
|
|
46
|
+
/** Set or change the PIN (6 to 12 digits). Needs the current password and a recent sign-in. */
|
|
47
|
+
async function setCibaPin(client, input) {
|
|
48
|
+
await call(client, '/v1/client/me/ciba_pin', json('PUT', { pin: input.pin, current_password: input.currentPassword }));
|
|
49
|
+
}
|
|
50
|
+
async function clearCibaPin(client, input = {}) {
|
|
51
|
+
await call(client, '/v1/client/me/ciba_pin', json('DELETE', { current_password: input.currentPassword }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=ciba.js.map
|
package/dist/ciba.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ciba.js","sourceRoot":"","sources":["../src/ciba.ts"],"names":[],"mappings":"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"}
|
package/dist/connections.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { FapiClient } from './fapi';
|
|
|
5
5
|
* an OAuth account a member shared), with live status. Authorizing an OAuth
|
|
6
6
|
* connection uses `connectExternalAccount` / `reauthorizeExternalAccount`.
|
|
7
7
|
*/
|
|
8
|
-
export type ConnectionStatus = 'connected' | 'not_connected' | 'needs_reauth';
|
|
8
|
+
export type ConnectionStatus = 'connected' | 'not_connected' | 'needs_reauth' | 'revoked' | 'error';
|
|
9
9
|
export interface AppConnection {
|
|
10
10
|
object: 'connection';
|
|
11
11
|
id: string;
|
|
@@ -13,20 +13,121 @@ export interface AppConnection {
|
|
|
13
13
|
type: 'organization' | 'user';
|
|
14
14
|
id: string;
|
|
15
15
|
};
|
|
16
|
-
kind: 'oauth' | 'api_key' | 'client_credentials';
|
|
16
|
+
kind: 'oauth' | 'api_key' | 'client_credentials' | 'bearer' | 'basic' | 'custom_header' | 'hmac_secret' | 'jwt_bearer' | 'oauth1' | 'github_app_installation' | 'admin_consent';
|
|
17
17
|
provider: string;
|
|
18
18
|
name: string;
|
|
19
19
|
allowed_hosts: string[];
|
|
20
20
|
status: ConnectionStatus;
|
|
21
|
+
/** Always `data`: a connection is never a sign-in method. */
|
|
22
|
+
purpose?: 'data';
|
|
23
|
+
environment?: 'production' | 'sandbox';
|
|
24
|
+
sandbox?: boolean;
|
|
25
|
+
/** The provider-side account the connection covers (a company, a workspace, a user id). */
|
|
26
|
+
external_id?: string | null;
|
|
27
|
+
host_params?: Record<string, string>;
|
|
28
|
+
scopes?: string[];
|
|
29
|
+
expires_at?: number | null;
|
|
30
|
+
/** Non-secret provider handles captured with the token (realmId, instance_url, team_id...). */
|
|
31
|
+
metadata?: Record<string, string>;
|
|
32
|
+
/** The provider's own error behind the status (`invalid_grant`, ...), with the HTTP status it answered. */
|
|
33
|
+
last_error?: {
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
httpStatus?: number | null;
|
|
37
|
+
at: number;
|
|
38
|
+
} | null;
|
|
39
|
+
/** Consecutive failed refreshes; 0 when healthy. */
|
|
40
|
+
refresh_failures?: number;
|
|
41
|
+
/** @deprecated Always null: a connection owns its tokens. */
|
|
21
42
|
external_account_id: string | null;
|
|
22
43
|
has_secret: boolean;
|
|
44
|
+
/** When the entered credential expires (epoch ms). The credential itself is never readable from the browser. */
|
|
45
|
+
secret_expires_at?: number | null;
|
|
23
46
|
}
|
|
24
|
-
/**
|
|
47
|
+
/** What the provider said when a connection was disconnected. The stored token is cleared in every case. */
|
|
48
|
+
export interface ConnectionRevokeResult {
|
|
49
|
+
/** `true` the provider confirmed; `'unsupported'` it has no revoke endpoint; `false` it refused or was unreachable (see `provider_error`). */
|
|
50
|
+
provider_revoked: boolean | 'unsupported' | 'not_connected';
|
|
51
|
+
provider_status: number | null;
|
|
52
|
+
provider_error: {
|
|
53
|
+
code: string;
|
|
54
|
+
description: string | null;
|
|
55
|
+
} | null;
|
|
56
|
+
local_cleared: true;
|
|
57
|
+
}
|
|
58
|
+
/** What to send when starting the provider authorization of a connection. */
|
|
59
|
+
export interface ConnectConnectionInput {
|
|
60
|
+
/** Where the owner lands afterwards; the URL carries `__atlas_status=connected` and `__atlas_connection=<id>`. */
|
|
61
|
+
redirectUrl: string;
|
|
62
|
+
/** Values for the provider's host templates, e.g. `{ subdomain: 'acme' }` or `{ tenant: 'contoso.onmicrosoft.com' }`. */
|
|
63
|
+
hostParams?: Record<string, string>;
|
|
64
|
+
environment?: 'production' | 'sandbox';
|
|
65
|
+
additionalScopes?: string[];
|
|
66
|
+
loginHint?: string;
|
|
67
|
+
display?: 'redirect' | 'popup';
|
|
68
|
+
/** A different provider account than the connection holds creates a sibling instead of failing with 409. */
|
|
69
|
+
createIfNew?: boolean;
|
|
70
|
+
}
|
|
71
|
+
export interface ConnectionAuthorization {
|
|
72
|
+
object: 'connection_authorization';
|
|
73
|
+
connection_id: string;
|
|
74
|
+
authorization_url: string;
|
|
75
|
+
attempt_id: string;
|
|
76
|
+
}
|
|
77
|
+
/** An organization's own OAuth client for a provider (the secret is write-only). */
|
|
78
|
+
export interface ConnectionOAuthClient {
|
|
79
|
+
object: 'connection_oauth_client';
|
|
80
|
+
id: string;
|
|
81
|
+
provider: string;
|
|
82
|
+
environment: 'production' | 'sandbox';
|
|
83
|
+
client_id: string;
|
|
84
|
+
has_secret: true;
|
|
85
|
+
scopes: string[];
|
|
86
|
+
host_params: Record<string, string>;
|
|
87
|
+
enabled: boolean;
|
|
88
|
+
callback_url: string;
|
|
89
|
+
}
|
|
90
|
+
export interface SetConnectionOAuthClientInput {
|
|
91
|
+
provider: string;
|
|
92
|
+
environment?: 'production' | 'sandbox';
|
|
93
|
+
clientId: string;
|
|
94
|
+
/** Required the first time; omit to keep the stored secret. */
|
|
95
|
+
clientSecret?: string;
|
|
96
|
+
scopes?: string[];
|
|
97
|
+
hostParams?: Record<string, string>;
|
|
98
|
+
enabled?: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Credential to enter for a non-OAuth connection. Write-only: it is sealed server-side and no browser call can read it
|
|
102
|
+
* back. Which fields apply depends on the connection's kind.
|
|
103
|
+
*/
|
|
25
104
|
export interface ConnectionCredentialsInput {
|
|
105
|
+
/** api_key */
|
|
26
106
|
apiKey?: string;
|
|
107
|
+
/** bearer */
|
|
108
|
+
token?: string;
|
|
109
|
+
/** basic */
|
|
110
|
+
username?: string;
|
|
111
|
+
password?: string;
|
|
112
|
+
/** custom_header */
|
|
113
|
+
value?: string;
|
|
114
|
+
/** hmac_secret */
|
|
115
|
+
secret?: string;
|
|
116
|
+
/** client_credentials */
|
|
27
117
|
clientId?: string;
|
|
28
118
|
clientSecret?: string;
|
|
29
119
|
tokenUrl?: string;
|
|
120
|
+
/** jwt_bearer / github_app_installation: a PEM private key, or (jwt_bearer) a Google service-account JSON key. */
|
|
121
|
+
privateKey?: string;
|
|
122
|
+
serviceAccountJson?: string;
|
|
123
|
+
/** oauth1 */
|
|
124
|
+
consumerKey?: string;
|
|
125
|
+
consumerSecret?: string;
|
|
126
|
+
tokenSecret?: string;
|
|
127
|
+
/** Epoch milliseconds or an ISO date; reminders go out 30, 7 and 1 days before. */
|
|
128
|
+
expiresAt?: number | string;
|
|
129
|
+
/** Non-secret settings of the kind (placement, header name, algorithm...). */
|
|
130
|
+
config?: Record<string, unknown>;
|
|
30
131
|
}
|
|
31
132
|
export declare class ConnectionRequestError extends Error {
|
|
32
133
|
readonly status: number;
|
|
@@ -41,3 +142,20 @@ export declare function listOrganizationConnections(client: FapiClient, organiza
|
|
|
41
142
|
export declare function setOrganizationConnectionCredentials(client: FapiClient, organizationId: string, connectionId: string, input: ConnectionCredentialsInput): Promise<AppConnection>;
|
|
42
143
|
/** Share the signed-in admin's own linked provider account with the organization. */
|
|
43
144
|
export declare function shareOrganizationConnection(client: FapiClient, organizationId: string, connectionId: string): Promise<AppConnection>;
|
|
145
|
+
/**
|
|
146
|
+
* Connect (or reconnect) one of the signed-in user's own connections. Navigate to `authorization_url`. This stores the
|
|
147
|
+
* tokens on the connection: it adds no sign-in method and needs no step-up.
|
|
148
|
+
*/
|
|
149
|
+
export declare function connectMyConnection(client: FapiClient, connectionId: string, input: ConnectConnectionInput): Promise<ConnectionAuthorization>;
|
|
150
|
+
/** Disconnect one of the signed-in user's own connections. The answer says whether the provider confirmed the revoke. */
|
|
151
|
+
export declare function revokeMyConnection(client: FapiClient, connectionId: string): Promise<AppConnection & ConnectionRevokeResult>;
|
|
152
|
+
/** Connect (or reconnect) an organization's connection (needs the org profile-manage permission, not a step-up). */
|
|
153
|
+
export declare function connectOrganizationConnection(client: FapiClient, organizationId: string, connectionId: string, input: ConnectConnectionInput): Promise<ConnectionAuthorization>;
|
|
154
|
+
/** Disconnect an organization's connection. */
|
|
155
|
+
export declare function revokeOrganizationConnection(client: FapiClient, organizationId: string, connectionId: string): Promise<AppConnection & ConnectionRevokeResult>;
|
|
156
|
+
/** The organization's own OAuth clients. */
|
|
157
|
+
export declare function listOrganizationOAuthClients(client: FapiClient, organizationId: string): Promise<ConnectionOAuthClient[]>;
|
|
158
|
+
/** Set the organization's own OAuth client for a provider; it overrides the instance client for its connections. */
|
|
159
|
+
export declare function setOrganizationOAuthClient(client: FapiClient, organizationId: string, input: SetConnectionOAuthClientInput): Promise<ConnectionOAuthClient>;
|
|
160
|
+
/** Delete the organization's OAuth client (refused while its connections hold tokens it issued). */
|
|
161
|
+
export declare function deleteOrganizationOAuthClient(client: FapiClient, organizationId: string, clientId: string): Promise<void>;
|
package/dist/connections.js
CHANGED
|
@@ -5,6 +5,13 @@ exports.listMyConnections = listMyConnections;
|
|
|
5
5
|
exports.listOrganizationConnections = listOrganizationConnections;
|
|
6
6
|
exports.setOrganizationConnectionCredentials = setOrganizationConnectionCredentials;
|
|
7
7
|
exports.shareOrganizationConnection = shareOrganizationConnection;
|
|
8
|
+
exports.connectMyConnection = connectMyConnection;
|
|
9
|
+
exports.revokeMyConnection = revokeMyConnection;
|
|
10
|
+
exports.connectOrganizationConnection = connectOrganizationConnection;
|
|
11
|
+
exports.revokeOrganizationConnection = revokeOrganizationConnection;
|
|
12
|
+
exports.listOrganizationOAuthClients = listOrganizationOAuthClients;
|
|
13
|
+
exports.setOrganizationOAuthClient = setOrganizationOAuthClient;
|
|
14
|
+
exports.deleteOrganizationOAuthClient = deleteOrganizationOAuthClient;
|
|
8
15
|
class ConnectionRequestError extends Error {
|
|
9
16
|
status;
|
|
10
17
|
code;
|
|
@@ -35,19 +42,76 @@ async function listOrganizationConnections(client, organizationId) {
|
|
|
35
42
|
}
|
|
36
43
|
/** Enter the organization's credential for a connection (needs the org profile-manage permission). */
|
|
37
44
|
function setOrganizationConnectionCredentials(client, organizationId, connectionId, input) {
|
|
45
|
+
const map = [
|
|
46
|
+
['apiKey', 'api_key'], ['token', 'token'], ['username', 'username'], ['password', 'password'], ['value', 'value'], ['secret', 'secret'],
|
|
47
|
+
['clientId', 'client_id'], ['clientSecret', 'client_secret'], ['tokenUrl', 'token_url'], ['privateKey', 'private_key'],
|
|
48
|
+
['serviceAccountJson', 'service_account_json'], ['consumerKey', 'consumer_key'], ['consumerSecret', 'consumer_secret'],
|
|
49
|
+
['tokenSecret', 'token_secret'], ['expiresAt', 'expires_at'], ['config', 'config'],
|
|
50
|
+
];
|
|
38
51
|
const body = {};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
body.client_id = input.clientId;
|
|
43
|
-
if (input.clientSecret !== undefined)
|
|
44
|
-
body.client_secret = input.clientSecret;
|
|
45
|
-
if (input.tokenUrl !== undefined)
|
|
46
|
-
body.token_url = input.tokenUrl;
|
|
52
|
+
for (const [from, to] of map)
|
|
53
|
+
if (input[from] !== undefined)
|
|
54
|
+
body[to] = input[from];
|
|
47
55
|
return call(client, `${orgBase(organizationId)}/${encodeURIComponent(connectionId)}/credentials`, { method: 'PUT', body: JSON.stringify(body) });
|
|
48
56
|
}
|
|
49
57
|
/** Share the signed-in admin's own linked provider account with the organization. */
|
|
50
58
|
function shareOrganizationConnection(client, organizationId, connectionId) {
|
|
51
59
|
return call(client, `${orgBase(organizationId)}/${encodeURIComponent(connectionId)}/share`, { method: 'POST', body: '{}' });
|
|
52
60
|
}
|
|
61
|
+
const connectBody = (i) => ({
|
|
62
|
+
redirect_url: i.redirectUrl,
|
|
63
|
+
...(i.hostParams ? { host_params: i.hostParams } : {}),
|
|
64
|
+
...(i.environment ? { environment: i.environment } : {}),
|
|
65
|
+
...(i.additionalScopes ? { additional_scopes: i.additionalScopes } : {}),
|
|
66
|
+
...(i.loginHint ? { login_hint: i.loginHint } : {}),
|
|
67
|
+
...(i.display ? { display: i.display } : {}),
|
|
68
|
+
...(i.createIfNew ? { create_if_new: true } : {}),
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Connect (or reconnect) one of the signed-in user's own connections. Navigate to `authorization_url`. This stores the
|
|
72
|
+
* tokens on the connection: it adds no sign-in method and needs no step-up.
|
|
73
|
+
*/
|
|
74
|
+
function connectMyConnection(client, connectionId, input) {
|
|
75
|
+
return call(client, `/v1/client/me/connections/${encodeURIComponent(connectionId)}/connect`, { method: 'POST', body: JSON.stringify(connectBody(input)) });
|
|
76
|
+
}
|
|
77
|
+
/** Disconnect one of the signed-in user's own connections. The answer says whether the provider confirmed the revoke. */
|
|
78
|
+
function revokeMyConnection(client, connectionId) {
|
|
79
|
+
return call(client, `/v1/client/me/connections/${encodeURIComponent(connectionId)}/revoke`, { method: 'POST', body: '{}' });
|
|
80
|
+
}
|
|
81
|
+
/** Connect (or reconnect) an organization's connection (needs the org profile-manage permission, not a step-up). */
|
|
82
|
+
function connectOrganizationConnection(client, organizationId, connectionId, input) {
|
|
83
|
+
return call(client, `${orgBase(organizationId)}/${encodeURIComponent(connectionId)}/connect`, { method: 'POST', body: JSON.stringify(connectBody(input)) });
|
|
84
|
+
}
|
|
85
|
+
/** Disconnect an organization's connection. */
|
|
86
|
+
function revokeOrganizationConnection(client, organizationId, connectionId) {
|
|
87
|
+
return call(client, `${orgBase(organizationId)}/${encodeURIComponent(connectionId)}/revoke`, { method: 'POST', body: '{}' });
|
|
88
|
+
}
|
|
89
|
+
const clientsBase = (organizationId) => `/v1/client/organizations/${encodeURIComponent(organizationId)}/connection_oauth_clients`;
|
|
90
|
+
/** The organization's own OAuth clients. */
|
|
91
|
+
async function listOrganizationOAuthClients(client, organizationId) {
|
|
92
|
+
return (await call(client, clientsBase(organizationId), { method: 'GET' })).data ?? [];
|
|
93
|
+
}
|
|
94
|
+
/** Set the organization's own OAuth client for a provider; it overrides the instance client for its connections. */
|
|
95
|
+
function setOrganizationOAuthClient(client, organizationId, input) {
|
|
96
|
+
return call(client, clientsBase(organizationId), {
|
|
97
|
+
method: 'PUT',
|
|
98
|
+
body: JSON.stringify({
|
|
99
|
+
provider: input.provider,
|
|
100
|
+
...(input.environment ? { environment: input.environment } : {}),
|
|
101
|
+
client_id: input.clientId,
|
|
102
|
+
...(input.clientSecret ? { client_secret: input.clientSecret } : {}),
|
|
103
|
+
...(input.scopes ? { scopes: input.scopes } : {}),
|
|
104
|
+
...(input.hostParams ? { host_params: input.hostParams } : {}),
|
|
105
|
+
...(input.enabled !== undefined ? { enabled: input.enabled } : {}),
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** Delete the organization's OAuth client (refused while its connections hold tokens it issued). */
|
|
110
|
+
async function deleteOrganizationOAuthClient(client, organizationId, clientId) {
|
|
111
|
+
const res = await client.request(`${clientsBase(organizationId)}/${encodeURIComponent(clientId)}`, { method: 'DELETE' });
|
|
112
|
+
if (!res.ok) {
|
|
113
|
+
const first = res.errors[0];
|
|
114
|
+
throw new ConnectionRequestError(res.status, first?.code ?? 'UNKNOWN', first?.message ?? 'The request failed.');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
53
117
|
//# sourceMappingURL=connections.js.map
|
package/dist/connections.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":";;;AAwJA,8CAEC;AAGD,kEAEC;AAGD,oFAeC;AAGD,kEAEC;AAgBD,kDAEC;AAGD,gDAEC;AAGD,sEAEC;AAGD,oEAEC;AAKD,oEAEC;AAGD,gEAaC;AAGD,sEAMC;AAtHD,MAAa,sBAAuB,SAAQ,KAAK;IAEpC;IACA;IAFX,YACW,MAAc,EACd,IAAY,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AATD,wDASC;AAED,KAAK,UAAU,IAAI,CAAI,MAAkB,EAAE,IAAY,EAAE,IAAiB;IACxE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,KAAK,EAAE,OAAO,IAAI,qBAAqB,CAAC,CAAC;IAClH,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC,4BAA4B,kBAAkB,CAAC,cAAc,CAAC,cAAc,CAAC;AAEzH,4CAA4C;AACrC,KAAK,UAAU,iBAAiB,CAAC,MAAkB;IACxD,OAAO,CAAC,MAAM,IAAI,CAA4B,MAAM,EAAE,2BAA2B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AACpH,CAAC;AAED,6CAA6C;AACtC,KAAK,UAAU,2BAA2B,CAAC,MAAkB,EAAE,cAAsB;IAC1F,OAAO,CAAC,MAAM,IAAI,CAA4B,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AAChH,CAAC;AAED,sGAAsG;AACtG,SAAgB,oCAAoC,CAClD,MAAkB,EAClB,cAAsB,EACtB,YAAoB,EACpB,KAAiC;IAEjC,MAAM,GAAG,GAAsD;QAC7D,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACvI,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC;QACtH,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;QACtH,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;KACnF,CAAC;IACF,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG;QAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS;YAAE,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACpF,OAAO,IAAI,CAAgB,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAClK,CAAC;AAED,qFAAqF;AACrF,SAAgB,2BAA2B,CAAC,MAAkB,EAAE,cAAsB,EAAE,YAAoB;IAC1G,OAAO,IAAI,CAAgB,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7I,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,CAAyB,EAAE,EAAE,CAAC,CAAC;IAClD,YAAY,EAAE,CAAC,CAAC,WAAW;IAC3B,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5C,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAClD,CAAC,CAAC;AAEH;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,MAAkB,EAAE,YAAoB,EAAE,KAA6B;IACzG,OAAO,IAAI,CAA0B,MAAM,EAAE,6BAA6B,kBAAkB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACtL,CAAC;AAED,yHAAyH;AACzH,SAAgB,kBAAkB,CAAC,MAAkB,EAAE,YAAoB;IACzE,OAAO,IAAI,CAAyC,MAAM,EAAE,6BAA6B,kBAAkB,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACtK,CAAC;AAED,oHAAoH;AACpH,SAAgB,6BAA6B,CAAC,MAAkB,EAAE,cAAsB,EAAE,YAAoB,EAAE,KAA6B;IAC3I,OAAO,IAAI,CAA0B,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvL,CAAC;AAED,+CAA+C;AAC/C,SAAgB,4BAA4B,CAAC,MAAkB,EAAE,cAAsB,EAAE,YAAoB;IAC3G,OAAO,IAAI,CAAyC,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACvK,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC,4BAA4B,kBAAkB,CAAC,cAAc,CAAC,2BAA2B,CAAC;AAE1I,4CAA4C;AACrC,KAAK,UAAU,4BAA4B,CAAC,MAAkB,EAAE,cAAsB;IAC3F,OAAO,CAAC,MAAM,IAAI,CAAoC,MAAM,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AAC5H,CAAC;AAED,oHAAoH;AACpH,SAAgB,0BAA0B,CAAC,MAAkB,EAAE,cAAsB,EAAE,KAAoC;IACzH,OAAO,IAAI,CAAwB,MAAM,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE;QACtE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,SAAS,EAAE,KAAK,CAAC,QAAQ;YACzB,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,oGAAoG;AAC7F,KAAK,UAAU,6BAA6B,CAAC,MAAkB,EAAE,cAAsB,EAAE,QAAgB;IAC9G,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAU,GAAG,WAAW,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,KAAK,EAAE,OAAO,IAAI,qBAAqB,CAAC,CAAC;IAClH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { FapiClient } from './fapi';
|
|
2
|
+
/** One entry of the public connector directory. */
|
|
3
|
+
export interface DirectoryConnector {
|
|
4
|
+
slug: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
category: string;
|
|
7
|
+
tagline: string | null;
|
|
8
|
+
logoUrl: string | null;
|
|
9
|
+
verified: boolean;
|
|
10
|
+
featured: boolean;
|
|
11
|
+
installCount: number;
|
|
12
|
+
source: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DirectoryFacets {
|
|
15
|
+
categories: {
|
|
16
|
+
category: string;
|
|
17
|
+
count: number;
|
|
18
|
+
}[];
|
|
19
|
+
total: number;
|
|
20
|
+
}
|
|
21
|
+
/** Search the public connector directory (built-in providers and community connectors) with category facets. */
|
|
22
|
+
export declare function listConnectorDirectory(client: FapiClient, opts?: {
|
|
23
|
+
q?: string;
|
|
24
|
+
category?: string;
|
|
25
|
+
verified?: boolean;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
connectors: DirectoryConnector[];
|
|
28
|
+
facets: DirectoryFacets;
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listConnectorDirectory = listConnectorDirectory;
|
|
4
|
+
/** Search the public connector directory (built-in providers and community connectors) with category facets. */
|
|
5
|
+
async function listConnectorDirectory(client, opts = {}) {
|
|
6
|
+
const qs = new URLSearchParams();
|
|
7
|
+
if (opts.q)
|
|
8
|
+
qs.set('q', opts.q);
|
|
9
|
+
if (opts.category)
|
|
10
|
+
qs.set('category', opts.category);
|
|
11
|
+
if (opts.verified)
|
|
12
|
+
qs.set('verified', 'true');
|
|
13
|
+
const res = await client.request(`/v1/public/connectors${qs.size ? `?${qs}` : ''}`, { method: 'GET' });
|
|
14
|
+
if (!res.ok || !res.data)
|
|
15
|
+
throw new Error(res.errors[0]?.message ?? 'Could not load the connector directory.');
|
|
16
|
+
return {
|
|
17
|
+
connectors: res.data.data.map((c) => ({
|
|
18
|
+
slug: c.slug, displayName: c.display_name, category: c.category, tagline: c.tagline ?? null, logoUrl: c.logo_url ?? null,
|
|
19
|
+
verified: Boolean(c.verified), featured: Boolean(c.featured), installCount: c.install_count ?? 0, source: c.source ?? 'builtin',
|
|
20
|
+
})),
|
|
21
|
+
facets: { categories: res.data.facets?.categories ?? [], total: res.data.facets?.total ?? res.data.data.length },
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=connector-directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-directory.js","sourceRoot":"","sources":["../src/connector-directory.ts"],"names":[],"mappings":";;AAiCA,wDAiBC;AAlBD,gHAAgH;AACzG,KAAK,UAAU,sBAAsB,CAC1C,MAAkB,EAClB,OAA8D,EAAE;IAEhE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,IAAI,IAAI,CAAC,CAAC;QAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,QAAQ;QAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,IAAI,CAAC,QAAQ;QAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAA6G,wBAAwB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACnN,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,yCAAyC,CAAC,CAAC;IAC/G,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;YACxH,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,aAAa,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;SAChI,CAAC,CAAC;QACH,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;KACjH,CAAC;AACJ,CAAC"}
|
package/dist/fapi.d.ts
CHANGED
|
@@ -248,6 +248,8 @@ export interface FlowState {
|
|
|
248
248
|
* server returns a new attempt.
|
|
249
249
|
*/
|
|
250
250
|
prepared?: 'email_code' | 'email_link' | null;
|
|
251
|
+
/** Cross-device link: the code to show on this device; the device that opens the link shows the same one. */
|
|
252
|
+
matchCode?: string | null;
|
|
251
253
|
/**
|
|
252
254
|
* After a sign-in completed here: true when this browser now holds the
|
|
253
255
|
* session, false when it didn't keep it (its cookie was blocked). Unset while
|
|
@@ -328,7 +330,31 @@ export declare function resendSignUpVerification(client: FapiClient, state: Flow
|
|
|
328
330
|
*/
|
|
329
331
|
export declare function awaitingSignUpLink(attempt: AttemptView | null | undefined, emailVerification: string | null | undefined): boolean;
|
|
330
332
|
/** §5.3: ask the server to send a code or a magic link. */
|
|
331
|
-
export declare function prepareFactor(client: FapiClient, state: FlowState, strategy: 'email_code' | 'email_link'
|
|
333
|
+
export declare function prepareFactor(client: FapiClient, state: FlowState, strategy: 'email_code' | 'email_link', opts?: {
|
|
334
|
+
crossDevice?: boolean;
|
|
335
|
+
}): Promise<FlowState>;
|
|
336
|
+
/** What the page the cross-device link opens needs: whether to ask for confirmation, and the code to compare. */
|
|
337
|
+
export interface CrossDeviceLinkPreview {
|
|
338
|
+
requiresConfirmation: boolean;
|
|
339
|
+
matchCode: string | null;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Cross-device magic link, second device: read the code from the opened link (`?attempt=&token=&cross_device=1`)
|
|
343
|
+
* so the page can show it next to the prompt "does this match the code on your other device?". Completes nothing.
|
|
344
|
+
*/
|
|
345
|
+
export declare function previewCrossDeviceLink(client: FapiClient, link: {
|
|
346
|
+
attempt: string;
|
|
347
|
+
token: string;
|
|
348
|
+
}): Promise<CrossDeviceLinkPreview | null>;
|
|
349
|
+
/**
|
|
350
|
+
* Cross-device magic link, second device: confirm with the code both devices show. The first device's
|
|
351
|
+
* `pollAttempt` then returns the ticket. One use; a wrong code invalidates the link.
|
|
352
|
+
*/
|
|
353
|
+
export declare function confirmCrossDeviceLink(client: FapiClient, link: {
|
|
354
|
+
attempt: string;
|
|
355
|
+
token: string;
|
|
356
|
+
matchCode: string;
|
|
357
|
+
}): Promise<boolean>;
|
|
332
358
|
/**
|
|
333
359
|
* §5.3 polling. Returns the updated flow, and a ticket once the link has been
|
|
334
360
|
* opened somewhere.
|