@vercel/connect 0.1.2 → 0.1.3
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/dist/ash/connection-authorization.d.ts +9 -2
- package/dist/ash/connection-authorization.js +7 -6
- package/dist/ash/slack-credentials.d.ts +22 -1
- package/dist/ash/slack-credentials.js +14 -3
- package/dist/authorization-details.d.ts +11 -0
- package/dist/authorization-details.js +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/token.d.ts +22 -10
- package/package.json +1 -1
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
* `@vercel/connect/ash` requires Ash to be installed in the consumer
|
|
29
29
|
* project, but the rest of `@vercel/connect` works without it.
|
|
30
30
|
*/
|
|
31
|
-
import { type InteractiveAuthorizationDefinition, type JsonValue, type NonInteractiveAuthorizationDefinition } from 'experimental-ash/connections';
|
|
32
|
-
import type { ConnectOptions, ConnectTokenParams } from '../token.js';
|
|
31
|
+
import { type ConnectionPrincipal, type InteractiveAuthorizationDefinition, type JsonValue, type NonInteractiveAuthorizationDefinition } from 'experimental-ash/connections';
|
|
32
|
+
import type { ConnectOptions, ConnectTokenParams, ConnectTokenSubject } from '../token.js';
|
|
33
33
|
/**
|
|
34
34
|
* Authorization phase passed to {@link AshAuthorizationOptions.onError}
|
|
35
35
|
* so consumers can branch their error translation per callback.
|
|
@@ -82,6 +82,13 @@ export interface AshAuthorizationOptions {
|
|
|
82
82
|
* `authorizationDetails`. Passed through verbatim.
|
|
83
83
|
*/
|
|
84
84
|
readonly tokenParams?: Omit<ConnectTokenParams, 'subject'>;
|
|
85
|
+
/**
|
|
86
|
+
* Override how Ash's framework-resolved principal is mapped to a
|
|
87
|
+
* Vercel Connect token subject. When omitted, app principals map to
|
|
88
|
+
* `{ type: "app" }` and user principals map to
|
|
89
|
+
* `{ type: "user", id, issuer }`.
|
|
90
|
+
*/
|
|
91
|
+
readonly principalToSubject?: (principal: ConnectionPrincipal) => ConnectTokenSubject | Promise<ConnectTokenSubject>;
|
|
85
92
|
/**
|
|
86
93
|
* Low-level Vercel Connect SDK options (currently `vercelToken`
|
|
87
94
|
* for overriding the OIDC bearer). Most callers leave this unset
|
|
@@ -50,7 +50,7 @@ function buildInteractiveDefinition(options) {
|
|
|
50
50
|
principalType: 'user',
|
|
51
51
|
async getToken({ principal }) {
|
|
52
52
|
try {
|
|
53
|
-
const response = await getTokenResponse(options.connector, buildTokenParams(options, principal), options.connectOptions);
|
|
53
|
+
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal), options.connectOptions);
|
|
54
54
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
55
55
|
}
|
|
56
56
|
catch (error) {
|
|
@@ -80,7 +80,7 @@ function buildInteractiveDefinition(options) {
|
|
|
80
80
|
// mints one URL, Vercel Connect redirects there" mental
|
|
81
81
|
// model. Revisit if tab-close timeouts become a real problem
|
|
82
82
|
// in production.
|
|
83
|
-
const response = await startAuthorization(options.connector, buildTokenParams(options, principal), {
|
|
83
|
+
const response = await startAuthorization(options.connector, await buildTokenParams(options, principal), {
|
|
84
84
|
...options.connectOptions,
|
|
85
85
|
callbackUrl: callbackUrl ?? webhook,
|
|
86
86
|
deviceCode: true,
|
|
@@ -105,7 +105,7 @@ function buildInteractiveDefinition(options) {
|
|
|
105
105
|
},
|
|
106
106
|
async completeAuthorization({ principal, }) {
|
|
107
107
|
try {
|
|
108
|
-
const response = await getTokenResponse(options.connector, buildTokenParams(options, principal), options.connectOptions);
|
|
108
|
+
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal), options.connectOptions);
|
|
109
109
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
110
110
|
}
|
|
111
111
|
catch (error) {
|
|
@@ -119,7 +119,7 @@ function buildNonInteractiveDefinition(options) {
|
|
|
119
119
|
principalType: 'app',
|
|
120
120
|
async getToken({ principal }) {
|
|
121
121
|
try {
|
|
122
|
-
const response = await getTokenResponse(options.connector, buildTokenParams(options, principal), options.connectOptions);
|
|
122
|
+
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal), options.connectOptions);
|
|
123
123
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
124
124
|
}
|
|
125
125
|
catch (error) {
|
|
@@ -128,10 +128,11 @@ function buildNonInteractiveDefinition(options) {
|
|
|
128
128
|
},
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
function buildTokenParams(options, principal) {
|
|
131
|
+
async function buildTokenParams(options, principal) {
|
|
132
|
+
const toSubject = options.principalToSubject ?? principalToSubject;
|
|
132
133
|
return {
|
|
133
134
|
...options.tokenParams,
|
|
134
|
-
subject:
|
|
135
|
+
subject: await toSubject(principal),
|
|
135
136
|
};
|
|
136
137
|
}
|
|
137
138
|
function principalToSubject(principal) {
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { SlackChannelCredentials } from 'experimental-ash/channels/slack';
|
|
2
|
+
import { type ConnectOptions, type ConnectTokenParams } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Token parameters accepted by {@link connectSlackCredentials}.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors {@link ConnectTokenParams} from `@vercel/connect`, minus
|
|
7
|
+
* `subject` — Slack bot tokens are always app-scoped, so `subject`
|
|
8
|
+
* is pinned to `{ type: "app" }` by this helper and cannot be
|
|
9
|
+
* overridden.
|
|
10
|
+
*/
|
|
11
|
+
export type ConnectSlackCredentialsParams = Omit<ConnectTokenParams, 'subject'>;
|
|
2
12
|
/**
|
|
3
13
|
* Build {@link SlackChannelCredentials} backed by a Vercel Connect
|
|
4
14
|
* connector that stores a Slack workspace's bot token.
|
|
@@ -13,6 +23,10 @@ import type { SlackChannelCredentials } from 'experimental-ash/channels/slack';
|
|
|
13
23
|
* with `subject: { type: "app" }`. End-user identity (per-user OAuth
|
|
14
24
|
* into Slack) is a separate concern handled elsewhere.
|
|
15
25
|
*
|
|
26
|
+
* The optional `params` and `options` arguments mirror the signature
|
|
27
|
+
* of {@link getToken}, allowing callers to pass through fields like
|
|
28
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
29
|
+
*
|
|
16
30
|
* ```ts
|
|
17
31
|
* import { slackRoute } from "experimental-ash/channels/slack";
|
|
18
32
|
* import { connectSlackCredentials } from "@vercel/connect/ash";
|
|
@@ -21,5 +35,12 @@ import type { SlackChannelCredentials } from 'experimental-ash/channels/slack';
|
|
|
21
35
|
* credentials: connectSlackCredentials("scl_..."),
|
|
22
36
|
* });
|
|
23
37
|
* ```
|
|
38
|
+
*
|
|
39
|
+
* Multi-workspace deployments can select a specific workspace install
|
|
40
|
+
* via `installationId`:
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* connectSlackCredentials("scl_...", { installationId: workspaceId });
|
|
44
|
+
* ```
|
|
24
45
|
*/
|
|
25
|
-
export declare function connectSlackCredentials(connector: string): SlackChannelCredentials;
|
|
46
|
+
export declare function connectSlackCredentials(connector: string, params?: ConnectSlackCredentialsParams, options?: ConnectOptions): SlackChannelCredentials;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getToken } from '../index.js';
|
|
1
|
+
import { getToken, } from '../index.js';
|
|
2
2
|
import { vercelOidc } from 'experimental-ash/channels/auth';
|
|
3
3
|
/**
|
|
4
4
|
* Build {@link SlackChannelCredentials} backed by a Vercel Connect
|
|
@@ -14,6 +14,10 @@ import { vercelOidc } from 'experimental-ash/channels/auth';
|
|
|
14
14
|
* with `subject: { type: "app" }`. End-user identity (per-user OAuth
|
|
15
15
|
* into Slack) is a separate concern handled elsewhere.
|
|
16
16
|
*
|
|
17
|
+
* The optional `params` and `options` arguments mirror the signature
|
|
18
|
+
* of {@link getToken}, allowing callers to pass through fields like
|
|
19
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
20
|
+
*
|
|
17
21
|
* ```ts
|
|
18
22
|
* import { slackRoute } from "experimental-ash/channels/slack";
|
|
19
23
|
* import { connectSlackCredentials } from "@vercel/connect/ash";
|
|
@@ -22,10 +26,17 @@ import { vercelOidc } from 'experimental-ash/channels/auth';
|
|
|
22
26
|
* credentials: connectSlackCredentials("scl_..."),
|
|
23
27
|
* });
|
|
24
28
|
* ```
|
|
29
|
+
*
|
|
30
|
+
* Multi-workspace deployments can select a specific workspace install
|
|
31
|
+
* via `installationId`:
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* connectSlackCredentials("scl_...", { installationId: workspaceId });
|
|
35
|
+
* ```
|
|
25
36
|
*/
|
|
26
|
-
export function connectSlackCredentials(connector) {
|
|
37
|
+
export function connectSlackCredentials(connector, params = {}, options) {
|
|
27
38
|
return {
|
|
28
|
-
botToken: () => getToken(connector, { subject: { type: 'app' } }),
|
|
39
|
+
botToken: () => getToken(connector, { ...params, subject: { type: 'app' } }, options),
|
|
29
40
|
webhookVerifier: vercelOidc(),
|
|
30
41
|
};
|
|
31
42
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ConnectAuthorizationDetail = ConnectGitHubAppInstallationAuthorizationDetail | ConnectCustomAuthorizationDetail;
|
|
2
|
+
export interface ConnectCustomAuthorizationDetail {
|
|
3
|
+
type: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface ConnectGitHubAppInstallationAuthorizationDetail {
|
|
7
|
+
type: 'github_app_installation';
|
|
8
|
+
org?: string;
|
|
9
|
+
permissions?: string | string[];
|
|
10
|
+
repositories?: string | string[];
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { getToken, getTokenResponse, ConnectError, NoValidTokenError, UserAuthorizationRequiredError, ConnectorInstallationRequiredError, type ConnectErrorOptions, type ConnectOptions, type ConnectTokenParams, type ConnectTokenResponse, type ConnectVendorErrorPayload, } from './token.js';
|
|
1
|
+
export { getToken, getTokenResponse, ConnectError, NoValidTokenError, UserAuthorizationRequiredError, ConnectorInstallationRequiredError, type ConnectErrorOptions, type ConnectOptions, type ConnectTokenParams, type ConnectTokenResponse, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from './token.js';
|
|
2
2
|
export { startAuthorization, type ConnectAuthorizationOptions, type ConnectAuthorizationResponse, } from './authorization.js';
|
|
3
|
+
export type { ConnectAuthorizationDetail } from './authorization-details.js';
|
package/dist/token.d.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
|
+
import type { ConnectAuthorizationDetail } from './authorization-details.js';
|
|
2
|
+
export type ConnectSubjectType = 'app' | 'user' | 'jwt-bearer';
|
|
3
|
+
export type ConnectTokenSubject = ConnectAppTokenSubject | ConnectUserTokenSubject | ConnectJwtBearerTokenSubject;
|
|
4
|
+
export interface ConnectAppTokenSubject {
|
|
5
|
+
type: 'app';
|
|
6
|
+
}
|
|
7
|
+
export interface ConnectUserTokenSubject {
|
|
8
|
+
type: 'user';
|
|
9
|
+
id: string;
|
|
10
|
+
issuer?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ConnectJwtBearerTokenSubject {
|
|
13
|
+
type: 'jwt-bearer';
|
|
14
|
+
sub: string;
|
|
15
|
+
/** Defaults to the connector's OAuth client id. */
|
|
16
|
+
iss?: string;
|
|
17
|
+
/** Defaults to the connector's OAuth token endpoint. */
|
|
18
|
+
aud?: string;
|
|
19
|
+
additionalClaims?: Record<string, unknown>;
|
|
20
|
+
}
|
|
1
21
|
export interface ConnectTokenParams {
|
|
2
|
-
subject:
|
|
3
|
-
type: 'app';
|
|
4
|
-
} | {
|
|
5
|
-
type: 'user';
|
|
6
|
-
id: string;
|
|
7
|
-
issuer?: string;
|
|
8
|
-
};
|
|
22
|
+
subject: ConnectTokenSubject;
|
|
9
23
|
installationId?: string;
|
|
10
24
|
audience?: string[];
|
|
11
25
|
scopes?: string[];
|
|
12
26
|
resources?: string[];
|
|
13
|
-
authorizationDetails?:
|
|
14
|
-
type: string;
|
|
15
|
-
} & Record<string, unknown>>;
|
|
27
|
+
authorizationDetails?: ConnectAuthorizationDetail[];
|
|
16
28
|
/**
|
|
17
29
|
* Buffer time in milliseconds before token expiration to consider it invalid.
|
|
18
30
|
* If the token expires within this buffer, it will be refreshed.
|