@flow-industries/id 0.26.5 → 0.27.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.
@@ -1,6 +1,7 @@
1
1
  import type { JWTPayload } from "jose";
2
2
  import type { AuthEventName } from "./events";
3
3
  import type { ManagedPdsEnrollment } from "./managed-provisioning";
4
+ import type { OAuthProviderSummary } from "./oauth";
4
5
  export type FlowUser = {
5
6
  id: string;
6
7
  username: string;
@@ -77,6 +78,8 @@ export type AuthResponse = {
77
78
  export type AuthConfig = {
78
79
  managedPdsEnabled?: boolean;
79
80
  atprotoEnabled?: boolean;
81
+ /** Enabled generic OAuth providers, sign-in and connect-only alike. */
82
+ oauthProviders?: OAuthProviderSummary[];
80
83
  rpId: string;
81
84
  rpName: string;
82
85
  };
@@ -0,0 +1,88 @@
1
+ import type { Context } from "hono";
2
+ import type { z } from "zod";
3
+ import type { githubOperations } from "../github/operations";
4
+ import type { GitHubScope } from "../github/scopes";
5
+ import type { RawRecord, RawValue } from "../json";
6
+ import type { OAuthCredential } from "./oauth";
7
+ export type { GitHubScope };
8
+ export type GitHubOperations = typeof githubOperations;
9
+ export type GitHubOperationId = keyof GitHubOperations;
10
+ export type GitHubOperationInput<Id extends GitHubOperationId> = z.input<GitHubOperations[Id]["input"]>;
11
+ export type GitHubOperationData<Id extends GitHubOperationId> = z.output<GitHubOperations[Id]["response"]>;
12
+ /** A connector success: the projected GitHub payload and, for paginated
13
+ * operations, the `page` to ask for next (null on the last page). */
14
+ export type GitHubConnectorResult<Id extends GitHubOperationId> = {
15
+ data: GitHubOperationData<Id>;
16
+ nextPage: number | null;
17
+ };
18
+ export type GitHubConnectorErrorCode = "GITHUB_CONNECTOR_DISABLED" | "ORIGIN_DENIED" | "SIGN_IN_REQUIRED" | "ACCOUNT_CHANGED" | "RATE_LIMITED" | "UNKNOWN_OPERATION" | "INVALID_BODY" | "TOO_LARGE" | "GITHUB_NOT_CONNECTED" | "GITHUB_RECONNECT_REQUIRED" | "GITHUB_SCOPE_REQUIRED" | "GITHUB_RATE_LIMITED" | "GITHUB_NOT_FOUND" | "GITHUB_FORBIDDEN" | "GITHUB_CONFLICT" | "GITHUB_VALIDATION_FAILED" | "GITHUB_UNAVAILABLE" | "GITHUB_INVALID_RESPONSE" | "CONNECTOR_UNAVAILABLE";
19
+ /** The connector's refusal body. `consentUrl` is the Flow ID page that
20
+ * connects GitHub or grants `requiredScopes`; `retryAfter` is in seconds. */
21
+ export type GitHubConnectorFailure = {
22
+ code: GitHubConnectorErrorCode;
23
+ requiredScopes?: GitHubScope[];
24
+ consentUrl?: string;
25
+ retryAfter?: number;
26
+ fields?: string[];
27
+ };
28
+ export type GitHubUpstreamRequest = {
29
+ method: "GET" | "POST" | "PATCH" | "PUT";
30
+ segments: readonly string[];
31
+ query?: Readonly<Record<string, string | undefined>>;
32
+ body?: RawRecord;
33
+ };
34
+ /** A validated operation call, with its schema-specific parts erased so the
35
+ * route can drive every operation through one code path. */
36
+ export type GitHubOperationPlan = {
37
+ ok: true;
38
+ request: GitHubUpstreamRequest;
39
+ scopes: readonly GitHubScope[];
40
+ repository: boolean;
41
+ paginated: boolean;
42
+ parse: (body: RawValue) => {
43
+ ok: true;
44
+ data: unknown;
45
+ } | {
46
+ ok: false;
47
+ };
48
+ } | {
49
+ ok: false;
50
+ fields: string[];
51
+ };
52
+ export type GitHubConnectorCaller = {
53
+ user: {
54
+ id: string;
55
+ isGuest?: boolean;
56
+ };
57
+ /** The Flow audience the caller's session or access token is bound to. */
58
+ audience: string;
59
+ };
60
+ export type GitHubConnectorDeps = {
61
+ enabled: boolean;
62
+ audienceAllowed: (audience: string) => boolean;
63
+ resolveCaller: (context: Context) => Promise<GitHubConnectorCaller | null>;
64
+ admit: (userId: string) => Promise<boolean>;
65
+ resolveGitHubCredential: (userId: string) => Promise<OAuthCredential | null>;
66
+ /** Drops a grant GitHub rejected, unless a newer one already replaced it,
67
+ * so the account page offers Reconnect instead of showing it connected. */
68
+ discardGitHubCredential: (credential: OAuthCredential) => Promise<void>;
69
+ consentUrl: (scopes: readonly GitHubScope[]) => string;
70
+ fetch: (input: URL, init: RequestInit) => Promise<Response>;
71
+ now: () => number;
72
+ };
73
+ export type GitHubConnectorCallOptions = {
74
+ signal?: AbortSignal;
75
+ };
76
+ /** The SDK's GitHub connector: Flow ID calls GitHub with the user's stored
77
+ * grant, so the app never holds a GitHub token. */
78
+ export type GitHubConnector = {
79
+ call<Id extends GitHubOperationId>(operation: Id, input: GitHubOperationInput<Id>, options?: GitHubConnectorCallOptions): Promise<GitHubConnectorResult<Id>>;
80
+ /** The Flow ID page that connects GitHub or adds `scopes` to the grant. */
81
+ consentUrl(scopes?: readonly GitHubScope[]): string;
82
+ /** Opens {@link GitHubConnector.consentUrl} in a new window; null when the
83
+ * browser blocked it or there is no window to open from. */
84
+ requestScopes(scopes?: readonly GitHubScope[]): Window | null;
85
+ };
86
+ export type GitHubConnectorOptions = {
87
+ fetch?: (input: string, init: RequestInit) => Promise<Response>;
88
+ };
File without changes
@@ -11,13 +11,15 @@ export type { AuthErrorCode, AuthEventName, AuthEventRecord, AuthMode, AuthOutco
11
11
  export type { ActiveAction, CatalogFieldRef, ClockAnchor, FinishedSummary, FocusApi, FocusPhase, FocusSessionEvent, FocusSessionState, StartFocusRequest, StudySearchHit, } from "./focus";
12
12
  export type { GameEventReport, GameLifecycleEventName, GameLifecycleFeedEvent, GameLifecycleFeedPage, GamePlayerSession, } from "./game";
13
13
  export { GAME_LIFECYCLE_EVENT_NAMES } from "./game";
14
+ export type { GitHubConnector, GitHubConnectorCaller, GitHubConnectorCallOptions, GitHubConnectorDeps, GitHubConnectorErrorCode, GitHubConnectorFailure, GitHubConnectorOptions, GitHubConnectorResult, GitHubOperationData, GitHubOperationId, GitHubOperationInput, GitHubOperationPlan, GitHubOperations, GitHubScope, GitHubUpstreamRequest, } from "./github-connector";
14
15
  export type { HostedOAuthMapping, HostedOAuthMappingReader, HostedOAuthProofOptions, HostedOAuthTransaction, } from "./hosted-oauth";
15
16
  export type { HostingQuotaAdmission, HostingQuotaLedger, HostingQuotaPolicy, HostingQuotaReservation, } from "./hosting-quota";
16
- export type { AccountProfileData } from "./landing";
17
+ export type { AccountProfileData, OAuthConnectionState } from "./landing";
17
18
  export type * from "./managed-provisioning";
18
19
  export type { Bridge, BridgeParameters, FlowAccount, FlowRemote, FlowRemoteConfig, FromWindowOptions, MessageResponse, Messenger, OneOf, Payload, QueuedRequest, ReadyOptions, RemoteFlowState, RemoteState, Schema, Storage, Topic, WithReady, } from "./messenger";
19
20
  export type { NoteBlob, NoteCollection, NoteOperation, NoteRecord, NoteResponses, NoteStoredRecord, NoteTransportDeps, NoteVaultHeader, } from "./note-transport";
20
21
  export type { MarkNotificationsReadInput, NotificationCounts, NotificationEntry, NotificationPage, NotificationReadResult, NotificationRefusal, } from "./notifications";
22
+ export type { OAuthCompletion, OAuthConnectionStatus, OAuthCredential, OAuthProfile, OAuthProviderSummary, OAuthStartRequest, OAuthStartResponse, OAuthStatus, } from "./oauth";
21
23
  export type { OtpVerificationFailure, OtpVerificationResult, VerificationAdapter, } from "./otp";
22
24
  export type { Call, ConnectCapabilities, ConnectResponse, MethodName, MethodParams, MethodResult, RestoreResponse, RpcRequest, SendCallsParams, SendCallsRequest, SendCallsResponse, SendTransactionParams, SendTransactionRequest, SendTransactionResponse, SignMessageRequest, SignMessageResponse, SignTypedDataRequest, SignTypedDataResponse, TransactionArgs, TypedData, TypedDataDomain, TypedDataField, } from "./protocol";
23
25
  export { isPersonalSignParams, isSendCallsParams, isSendTransactionParams, } from "./protocol";
@@ -1,4 +1,5 @@
1
1
  import type { FlowUser } from "./auth";
2
+ import type { OAuthStatus } from "./oauth";
2
3
  export type AccountProfileData = FlowUser & {
3
4
  bio?: string | null;
4
5
  email?: string | null;
@@ -8,3 +9,22 @@ export type AccountProfileData = FlowUser & {
8
9
  image?: string | null;
9
10
  walletAddress?: string | null;
10
11
  };
12
+ /** One provider's account-page connection, as the shared hook drives it. */
13
+ export type OAuthConnectionState = {
14
+ status: OAuthStatus | null;
15
+ connection: OAuthStatus["connection"];
16
+ connected: boolean;
17
+ /** The provider account the row names, once one is linked. */
18
+ detail: string | null;
19
+ statusText: string | null;
20
+ /** Why disconnecting is blocked, with the id the disabled button points at. */
21
+ blockedHint: {
22
+ id: string;
23
+ text: string;
24
+ } | null;
25
+ pending: boolean;
26
+ error: string | null;
27
+ /** Leaves for the provider; extra `scopes` are added to those already granted. */
28
+ connect(scopes?: string[]): Promise<void>;
29
+ unlink(): Promise<void>;
30
+ };
@@ -0,0 +1,64 @@
1
+ /** A provider token held server-side for one external account; never sent to a browser. */
2
+ export type OAuthCredential = {
3
+ accessToken: string;
4
+ refreshToken?: string;
5
+ /** Epoch milliseconds; absent when the provider issues non-expiring tokens. */
6
+ expiresAt?: number;
7
+ scopes: string[];
8
+ tokenType: string;
9
+ /** The provider's stable subject, equal to `account.accountId`. */
10
+ subject: string;
11
+ };
12
+ /** What a provider's `profile()` mapper extracts from its token and userinfo responses. */
13
+ export type OAuthProfile = {
14
+ subject: string;
15
+ displayName?: string | null;
16
+ usernameHint?: string | null;
17
+ email?: string | null;
18
+ emailVerified?: boolean;
19
+ };
20
+ /** An enabled generic provider as the hosted page and account page see it. */
21
+ export type OAuthProviderSummary = {
22
+ id: string;
23
+ displayName: string;
24
+ /** False for connect-only providers, which never count as a sign-in method. */
25
+ signIn: boolean;
26
+ };
27
+ export type OAuthStartRequest = {
28
+ intent: "login" | "link";
29
+ transaction?: string;
30
+ expectedUserId?: string;
31
+ invitationCode?: string;
32
+ /** Extra scopes from the provider's requestable set, unioned with granted ones. */
33
+ scopes?: string[];
34
+ };
35
+ export type OAuthStartResponse = {
36
+ url: string;
37
+ completionToken: string;
38
+ };
39
+ export type OAuthCompletion = {
40
+ user: {
41
+ id: string;
42
+ username: string;
43
+ isGuest: false;
44
+ };
45
+ } | {
46
+ linked: true;
47
+ };
48
+ export type OAuthConnectionStatus = "connected" | "reconnect_required";
49
+ export type OAuthStatus = {
50
+ provider: string;
51
+ displayName: string;
52
+ enabled: boolean;
53
+ signIn: boolean;
54
+ connection: {
55
+ accountId: string;
56
+ displayName: string | null;
57
+ status: OAuthConnectionStatus;
58
+ /** Granted scopes for providers that keep a credential; empty otherwise. */
59
+ scopes: string[];
60
+ } | null;
61
+ requestableScopes: string[];
62
+ canUnlink: boolean;
63
+ unlinkBlockReason: string | null;
64
+ };
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flow-industries/id",
3
- "version": "0.26.5",
3
+ "version": "0.27.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",