@authara/react 0.0.1-trusted.3 → 0.2.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,137 @@
1
+ export async function runGoogleAction(client, selected, proof) {
2
+ await client.getCsrfToken();
3
+ const body = { code: proof.code, redirect_uri: proof.redirect_uri };
4
+ switch (selected.action) {
5
+ case "login":
6
+ return {
7
+ action: "login",
8
+ provider: "google",
9
+ session: await client.loginWithGoogle({
10
+ audience: selected.audience,
11
+ body,
12
+ }),
13
+ };
14
+ case "link":
15
+ await client.linkCurrentUserGoogle({ body });
16
+ return { action: "link", provider: "google" };
17
+ case "reauthenticate":
18
+ await client.reauthenticateWithGoogle({
19
+ body: {
20
+ ...body,
21
+ authentication_challenge_id: selected.authenticationChallengeId,
22
+ },
23
+ });
24
+ return { action: "reauthenticate", provider: "google" };
25
+ case "recover":
26
+ return {
27
+ action: "recover",
28
+ provider: "google",
29
+ session: await client.completeAccountRecoveryLinkWithGoogle({
30
+ linkID: selected.recoveryLinkId,
31
+ audience: selected.audience,
32
+ body,
33
+ }),
34
+ };
35
+ }
36
+ }
37
+ export async function runAppleAction(client, selected, proof) {
38
+ await client.getCsrfToken();
39
+ switch (selected.action) {
40
+ case "login":
41
+ return {
42
+ action: "login",
43
+ provider: "apple",
44
+ session: await client.loginWithApple({
45
+ audience: selected.audience,
46
+ body: proof,
47
+ }),
48
+ };
49
+ case "link":
50
+ await client.linkCurrentUserApple({ body: proof });
51
+ return { action: "link", provider: "apple" };
52
+ case "reauthenticate":
53
+ await client.reauthenticateWithApple({
54
+ body: {
55
+ ...proof,
56
+ authentication_challenge_id: selected.authenticationChallengeId,
57
+ },
58
+ });
59
+ return { action: "reauthenticate", provider: "apple" };
60
+ case "recover":
61
+ return {
62
+ action: "recover",
63
+ provider: "apple",
64
+ session: await client.completeAccountRecoveryLinkWithApple({
65
+ linkID: selected.recoveryLinkId,
66
+ audience: selected.audience,
67
+ body: proof,
68
+ }),
69
+ };
70
+ }
71
+ }
72
+ export async function runMicrosoftAction(client, selected, proof) {
73
+ await client.getCsrfToken();
74
+ switch (selected.action) {
75
+ case "login":
76
+ if (!client.loginWithMicrosoft)
77
+ throw microsoftClientUnavailable();
78
+ return {
79
+ action: "login",
80
+ provider: "microsoft",
81
+ session: await client.loginWithMicrosoft({
82
+ audience: selected.audience,
83
+ body: proof,
84
+ }),
85
+ };
86
+ case "link":
87
+ if (!client.linkCurrentUserMicrosoft)
88
+ throw microsoftClientUnavailable();
89
+ await client.linkCurrentUserMicrosoft({ body: proof });
90
+ return { action: "link", provider: "microsoft" };
91
+ case "reauthenticate":
92
+ if (!client.reauthenticateWithMicrosoft)
93
+ throw microsoftClientUnavailable();
94
+ await client.reauthenticateWithMicrosoft({
95
+ body: {
96
+ ...proof,
97
+ authentication_challenge_id: selected.authenticationChallengeId,
98
+ },
99
+ });
100
+ return { action: "reauthenticate", provider: "microsoft" };
101
+ case "recover":
102
+ if (!client.completeAccountRecoveryLinkWithMicrosoft)
103
+ throw microsoftClientUnavailable();
104
+ return {
105
+ action: "recover",
106
+ provider: "microsoft",
107
+ session: await client.completeAccountRecoveryLinkWithMicrosoft({
108
+ linkID: selected.recoveryLinkId,
109
+ audience: selected.audience,
110
+ body: proof,
111
+ }),
112
+ };
113
+ }
114
+ }
115
+ function microsoftClientUnavailable() {
116
+ return {
117
+ status: 404,
118
+ message: "This @authara/browser client does not include Microsoft authentication.",
119
+ };
120
+ }
121
+ export function resolveAction(action, audience, authenticationChallengeId, recoveryLinkId) {
122
+ if (action === "link")
123
+ return { action };
124
+ if (action === "reauthenticate") {
125
+ if (!authenticationChallengeId) {
126
+ throw new Error("authenticationChallengeId is required for reauthentication.");
127
+ }
128
+ return { action, authenticationChallengeId };
129
+ }
130
+ if (action === "recover") {
131
+ if (!recoveryLinkId) {
132
+ throw new Error("recoveryLinkId is required for account recovery.");
133
+ }
134
+ return { action, audience: "app", recoveryLinkId };
135
+ }
136
+ return { action: "login", audience: audience ?? "app" };
137
+ }
@@ -0,0 +1,3 @@
1
+ export type AutharaColorMode = "dark" | "light" | "system";
2
+ export type ResolvedAutharaColorMode = Exclude<AutharaColorMode, "system">;
3
+ export declare function useResolvedAutharaColorMode(mode: AutharaColorMode): ResolvedAutharaColorMode;
@@ -0,0 +1,20 @@
1
+ import { useSyncExternalStore } from "react";
2
+ const darkModeQuery = "(prefers-color-scheme: dark)";
3
+ function systemColorMode() {
4
+ if (typeof window === "undefined" || !window.matchMedia)
5
+ return "light";
6
+ return window.matchMedia(darkModeQuery).matches ? "dark" : "light";
7
+ }
8
+ function subscribeSystemColorMode(update) {
9
+ if (typeof window === "undefined" || !window.matchMedia)
10
+ return () => { };
11
+ const query = window.matchMedia(darkModeQuery);
12
+ query.addEventListener("change", update);
13
+ return () => query.removeEventListener("change", update);
14
+ }
15
+ const noSubscription = () => () => { };
16
+ const serverColorMode = () => "light";
17
+ export function useResolvedAutharaColorMode(mode) {
18
+ const systemMode = useSyncExternalStore(mode === "system" ? subscribeSystemColorMode : noSubscription, systemColorMode, serverColorMode);
19
+ return mode === "system" ? systemMode : mode;
20
+ }
package/dist/context.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { type PropsWithChildren } from "react";
2
2
  import type { AutharaReactClient } from "./contract.js";
3
- import { AppleService, GoogleService } from "./services.js";
3
+ import { AppleService, GoogleService, MicrosoftService } from "./services.js";
4
4
  type AutharaReactContextValue = {
5
5
  apple: AppleService;
6
+ client: AutharaReactClient;
6
7
  google: GoogleService;
8
+ microsoft: MicrosoftService;
7
9
  };
8
10
  export type AutharaProviderProps = PropsWithChildren<{
9
11
  client: AutharaReactClient;
10
12
  }>;
11
13
  /**
12
- * Owns the page-wide Google and Apple SDK configuration. Use one provider per
13
- * document so Google Identity Services is initialized only once.
14
+ * Owns the page-wide external-provider SDK configuration.
14
15
  */
15
16
  export declare function AutharaProvider({ client, children, }: AutharaProviderProps): React.JSX.Element;
16
17
  export declare function useAutharaServices(): AutharaReactContextValue;
package/dist/context.js CHANGED
@@ -1,15 +1,16 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useMemo, } from "react";
3
- import { AppleService, GoogleService } from "./services.js";
3
+ import { AppleService, GoogleService, MicrosoftService } from "./services.js";
4
4
  const AutharaContext = createContext(null);
5
5
  /**
6
- * Owns the page-wide Google and Apple SDK configuration. Use one provider per
7
- * document so Google Identity Services is initialized only once.
6
+ * Owns the page-wide external-provider SDK configuration.
8
7
  */
9
8
  export function AutharaProvider({ client, children, }) {
10
9
  const value = useMemo(() => ({
11
10
  apple: new AppleService(client),
11
+ client,
12
12
  google: new GoogleService(client),
13
+ microsoft: new MicrosoftService(client),
13
14
  }), [client]);
14
15
  return (_jsx(AutharaContext.Provider, { value: value, children: children }));
15
16
  }
@@ -1,3 +1,12 @@
1
+ import type { AccountRecoveryLink as BrowserAccountRecoveryLink, AuthSession } from "@authara/browser";
2
+ import type { AutharaButtonError, AutharaLinkErrorCode, AutharaLoginErrorCode, AutharaRecoveryErrorCode, AutharaReauthenticationErrorCode } from "./errors.js";
3
+ export type AutharaAudience = "app" | "admin" | "operator";
4
+ export type AutharaAction = "login" | "link" | "reauthenticate" | "recover";
5
+ export type AutharaProviderName = "apple" | "google" | "microsoft";
6
+ export type AutharaAccountRecoveryLink = Omit<BrowserAccountRecoveryLink, "provider" | "proof_methods"> & {
7
+ provider: AutharaProviderName;
8
+ proof_methods: Array<"password" | AutharaProviderName>;
9
+ };
1
10
  export interface GoogleLoginOptions {
2
11
  client_id: string;
3
12
  nonce: string;
@@ -8,13 +17,131 @@ export interface AppleLoginOptions {
8
17
  state: string;
9
18
  nonce: string;
10
19
  }
20
+ export interface MicrosoftLoginOptions {
21
+ client_id: string;
22
+ authority: string;
23
+ nonce: string;
24
+ }
25
+ export type GoogleProof = {
26
+ code: string;
27
+ redirect_uri: string;
28
+ };
29
+ export type AppleProof = {
30
+ code: string;
31
+ state: string;
32
+ };
33
+ export type MicrosoftProof = {
34
+ credential: string;
35
+ nonce: string;
36
+ };
11
37
  /**
12
38
  * The generated @authara/browser contract slice used by the React components.
13
- * AutharaBrowserClient satisfies this interface once both providers are
14
- * available in the released Core contract.
39
+ * AutharaBrowserClient satisfies the required provider methods from the
40
+ * released Core contract. Microsoft remains optional during SDK rollout.
15
41
  */
16
42
  export interface AutharaReactClient {
43
+ getCsrfToken(): Promise<unknown>;
17
44
  getGoogleLoginOptions(): Promise<GoogleLoginOptions>;
18
45
  getAppleLoginOptions(): Promise<AppleLoginOptions>;
46
+ loginWithGoogle(options: {
47
+ audience?: AutharaAudience;
48
+ body: GoogleProof;
49
+ }): Promise<AuthSession>;
50
+ loginWithApple(options: {
51
+ audience?: AutharaAudience;
52
+ body: AppleProof;
53
+ }): Promise<AuthSession>;
54
+ linkCurrentUserGoogle(options: {
55
+ body: GoogleProof;
56
+ }): Promise<void>;
57
+ linkCurrentUserApple(options: {
58
+ body: AppleProof;
59
+ }): Promise<void>;
60
+ reauthenticateWithGoogle(options: {
61
+ body: GoogleProof & {
62
+ authentication_challenge_id: string;
63
+ };
64
+ }): Promise<void>;
65
+ reauthenticateWithApple(options: {
66
+ body: AppleProof & {
67
+ authentication_challenge_id: string;
68
+ };
69
+ }): Promise<void>;
70
+ completeAccountRecoveryLinkWithGoogle(options: {
71
+ linkID: AutharaAccountRecoveryLink["link_id"];
72
+ audience?: "app";
73
+ body: GoogleProof;
74
+ }): Promise<AuthSession>;
75
+ completeAccountRecoveryLinkWithApple(options: {
76
+ linkID: AutharaAccountRecoveryLink["link_id"];
77
+ audience?: "app";
78
+ body: AppleProof;
79
+ }): Promise<AuthSession>;
80
+ getMicrosoftLoginOptions?(): Promise<MicrosoftLoginOptions>;
81
+ loginWithMicrosoft?(options: {
82
+ audience?: AutharaAudience;
83
+ body: MicrosoftProof;
84
+ }): Promise<AuthSession>;
85
+ linkCurrentUserMicrosoft?(options: {
86
+ body: MicrosoftProof;
87
+ }): Promise<void>;
88
+ reauthenticateWithMicrosoft?(options: {
89
+ body: MicrosoftProof & {
90
+ authentication_challenge_id: string;
91
+ };
92
+ }): Promise<void>;
93
+ completeAccountRecoveryLinkWithMicrosoft?(options: {
94
+ linkID: AutharaAccountRecoveryLink["link_id"];
95
+ audience?: "app";
96
+ body: MicrosoftProof;
97
+ }): Promise<AuthSession>;
19
98
  }
99
+ export type AutharaLoginSuccess<P extends AutharaProviderName> = {
100
+ action: "login";
101
+ provider: P;
102
+ session: AuthSession;
103
+ };
104
+ export type AutharaLinkSuccess<P extends AutharaProviderName> = {
105
+ action: "link";
106
+ provider: P;
107
+ };
108
+ export type AutharaReauthenticationSuccess<P extends AutharaProviderName> = {
109
+ action: "reauthenticate";
110
+ provider: P;
111
+ };
112
+ export type AutharaRecoverySuccess<P extends AutharaProviderName> = {
113
+ action: "recover";
114
+ provider: P;
115
+ session: AuthSession;
116
+ };
117
+ export type AutharaActionSuccess<P extends AutharaProviderName> = AutharaLoginSuccess<P> | AutharaLinkSuccess<P> | AutharaReauthenticationSuccess<P> | AutharaRecoverySuccess<P>;
118
+ export type AutharaActionProps<P extends AutharaProviderName> = {
119
+ action?: "login";
120
+ audience?: AutharaAudience;
121
+ authenticationChallengeId?: never;
122
+ recoveryLinkId?: never;
123
+ onSuccess?: (result: AutharaLoginSuccess<P>) => MaybePromise<void>;
124
+ onError?: (error: AutharaButtonError<AutharaLoginErrorCode>) => void;
125
+ } | {
126
+ action: "link";
127
+ audience?: never;
128
+ authenticationChallengeId?: never;
129
+ recoveryLinkId?: never;
130
+ onSuccess?: (result: AutharaLinkSuccess<P>) => MaybePromise<void>;
131
+ onError?: (error: AutharaButtonError<AutharaLinkErrorCode>) => void;
132
+ } | {
133
+ action: "reauthenticate";
134
+ audience?: never;
135
+ authenticationChallengeId: string;
136
+ recoveryLinkId?: never;
137
+ onSuccess?: (result: AutharaReauthenticationSuccess<P>) => MaybePromise<void>;
138
+ onError?: (error: AutharaButtonError<AutharaReauthenticationErrorCode>) => void;
139
+ } | {
140
+ action: "recover";
141
+ audience?: "app";
142
+ authenticationChallengeId?: never;
143
+ recoveryLinkId: AutharaAccountRecoveryLink["link_id"];
144
+ onSuccess?: (result: AutharaRecoverySuccess<P>) => MaybePromise<void>;
145
+ onError?: (error: AutharaButtonError<AutharaRecoveryErrorCode>) => void;
146
+ };
20
147
  export type MaybePromise<T> = T | Promise<T>;
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,37 @@
1
+ import type { AutharaAccountRecoveryLink } from "./contract.js";
2
+ import { type AutharaContractErrorCode } from "./generated-error-codes.js";
1
3
  export declare function isProviderUnavailable(error: unknown): boolean;
2
4
  export declare function toError(error: unknown, fallback: string): Error;
5
+ export type AutharaButtonErrorSource = "authara" | "provider" | "configuration" | "consumer";
6
+ export type AutharaLocalErrorCode = "csrf_token_missing" | "unknown_authara_error";
7
+ export type AutharaLoginErrorCode = AutharaContractErrorCode<"login"> | AutharaLocalErrorCode;
8
+ export type AutharaLinkErrorCode = AutharaContractErrorCode<"link"> | AutharaLocalErrorCode;
9
+ export type AutharaReauthenticationErrorCode = AutharaContractErrorCode<"reauthenticate"> | AutharaLocalErrorCode;
10
+ export type AutharaRecoveryErrorCode = AutharaContractErrorCode<"recover"> | AutharaLocalErrorCode;
11
+ export type AutharaButtonErrorCode = AutharaLoginErrorCode | AutharaLinkErrorCode | AutharaReauthenticationErrorCode | AutharaRecoveryErrorCode;
12
+ export type AutharaAuthenticationChallenge = {
13
+ id: string;
14
+ expires_at: string;
15
+ };
16
+ export declare class AutharaButtonError<Code extends string = AutharaButtonErrorCode> extends Error {
17
+ readonly source: AutharaButtonErrorSource;
18
+ readonly code?: Code;
19
+ readonly serverCode?: string;
20
+ readonly status?: number;
21
+ readonly authenticationChallenge?: AutharaAuthenticationChallenge;
22
+ readonly reauthenticateUrl?: string;
23
+ readonly recovery?: AutharaAccountRecoveryLink;
24
+ readonly originalError: unknown;
25
+ constructor(message: string, source: AutharaButtonErrorSource, originalError: unknown, metadata?: {
26
+ code?: Code;
27
+ serverCode?: string;
28
+ status?: number;
29
+ authenticationChallenge?: AutharaAuthenticationChallenge;
30
+ reauthenticateUrl?: string;
31
+ recovery?: AutharaAccountRecoveryLink;
32
+ });
33
+ }
34
+ export declare function toAutharaButtonError(error: unknown, fallback: string, defaultSource: AutharaButtonErrorSource): AutharaButtonError;
35
+ export declare function isAutharaButtonError(error: unknown): error is AutharaButtonError;
3
36
  export declare function isAppleCancellation(error: unknown): boolean;
37
+ export declare function isMicrosoftCancellation(error: unknown): boolean;
package/dist/errors.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { autharaActionErrorCodes, } from "./generated-error-codes.js";
1
2
  export function isProviderUnavailable(error) {
2
3
  return (typeof error === "object" &&
3
4
  error !== null &&
@@ -16,6 +17,101 @@ export function toError(error, fallback) {
16
17
  }
17
18
  return new Error(fallback);
18
19
  }
20
+ const knownAutharaErrorCodes = new Set([
21
+ ...autharaActionErrorCodes.login,
22
+ ...autharaActionErrorCodes.link,
23
+ ...autharaActionErrorCodes.reauthenticate,
24
+ ...autharaActionErrorCodes.recover,
25
+ "csrf_token_missing",
26
+ ]);
27
+ export class AutharaButtonError extends Error {
28
+ constructor(message, source, originalError, metadata = {}) {
29
+ super(message);
30
+ this.name = "AutharaButtonError";
31
+ this.source = source;
32
+ this.originalError = originalError;
33
+ this.code = metadata.code;
34
+ this.serverCode = metadata.serverCode;
35
+ this.status = metadata.status;
36
+ this.authenticationChallenge = metadata.authenticationChallenge;
37
+ this.reauthenticateUrl = metadata.reauthenticateUrl;
38
+ this.recovery = metadata.recovery;
39
+ }
40
+ }
41
+ function record(value) {
42
+ return typeof value === "object" && value !== null
43
+ ? value
44
+ : undefined;
45
+ }
46
+ function challengeFrom(error) {
47
+ const details = record(error?.details);
48
+ const candidate = record(error?.authenticationChallenge) ??
49
+ record(details?.authentication_challenge);
50
+ if (typeof candidate?.id !== "string" ||
51
+ typeof candidate.expires_at !== "string") {
52
+ return undefined;
53
+ }
54
+ return { id: candidate.id, expires_at: candidate.expires_at };
55
+ }
56
+ function recoveryFrom(error) {
57
+ const details = record(error?.details);
58
+ const candidate = record(error?.recovery) ?? record(details?.recovery);
59
+ if (typeof candidate?.link_id !== "string" ||
60
+ !candidate.link_id ||
61
+ typeof candidate.provider !== "string" ||
62
+ !candidate.provider ||
63
+ !Array.isArray(candidate.proof_methods) ||
64
+ !candidate.proof_methods.every((method) => typeof method === "string")) {
65
+ return undefined;
66
+ }
67
+ return {
68
+ link_id: candidate.link_id,
69
+ provider: candidate.provider,
70
+ proof_methods: candidate.proof_methods,
71
+ };
72
+ }
73
+ export function toAutharaButtonError(error, fallback, defaultSource) {
74
+ if (error instanceof AutharaButtonError)
75
+ return error;
76
+ const value = record(error);
77
+ const details = record(value?.details);
78
+ const nestedError = record(details?.error);
79
+ const status = typeof value?.status === "number" ? value.status : undefined;
80
+ const rawCode = typeof value?.code === "string"
81
+ ? value.code
82
+ : typeof nestedError?.code === "string"
83
+ ? nestedError.code
84
+ : value?.name === "AutharaCSRFError"
85
+ ? "csrf_token_missing"
86
+ : undefined;
87
+ const autharaFailure = status !== undefined ||
88
+ details !== undefined ||
89
+ value?.name === "AutharaApiError" ||
90
+ value?.name === "AutharaCSRFError";
91
+ const source = autharaFailure ? "authara" : defaultSource;
92
+ const normalized = toError(error, fallback);
93
+ const reauthenticateUrl = typeof value?.reauthenticateUrl === "string"
94
+ ? value.reauthenticateUrl
95
+ : typeof details?.reauthenticate_url === "string"
96
+ ? details.reauthenticate_url
97
+ : undefined;
98
+ const knownCode = rawCode !== undefined && knownAutharaErrorCodes.has(rawCode);
99
+ return new AutharaButtonError(normalized.message, source, error, {
100
+ code: source === "authara"
101
+ ? (knownCode
102
+ ? rawCode
103
+ : "unknown_authara_error")
104
+ : undefined,
105
+ serverCode: source === "authara" && !knownCode ? rawCode : undefined,
106
+ status,
107
+ authenticationChallenge: challengeFrom(value),
108
+ reauthenticateUrl,
109
+ recovery: recoveryFrom(value),
110
+ });
111
+ }
112
+ export function isAutharaButtonError(error) {
113
+ return error instanceof AutharaButtonError;
114
+ }
19
115
  export function isAppleCancellation(error) {
20
116
  if (typeof error !== "object" || error === null || !("error" in error)) {
21
117
  return false;
@@ -23,3 +119,11 @@ export function isAppleCancellation(error) {
23
119
  return (error.error === "user_cancelled_authorize" ||
24
120
  error.error === "popup_closed_by_user");
25
121
  }
122
+ export function isMicrosoftCancellation(error) {
123
+ if (typeof error !== "object" || error === null || !("errorCode" in error)) {
124
+ return false;
125
+ }
126
+ return (error.errorCode === "user_cancelled" ||
127
+ error.errorCode === "popup_window_error" ||
128
+ error.errorCode === "empty_window_error");
129
+ }
@@ -0,0 +1,8 @@
1
+ export declare const autharaActionErrorCodes: {
2
+ readonly login: readonly ["account_link_required", "forbidden", "internal_error", "invalid_request", "not_found", "unauthorized"];
3
+ readonly link: readonly ["auth_method_already_linked", "forbidden", "internal_error", "invalid_request", "not_found", "recent_authentication_required", "unauthorized"];
4
+ readonly reauthenticate: readonly ["internal_error", "invalid_authentication_challenge", "invalid_request", "not_found", "unauthorized"];
5
+ readonly recover: readonly ["auth_method_already_linked", "forbidden", "internal_error", "invalid_request", "invitation_already_accepted", "invitation_email_mismatch", "invitation_expired", "invitation_not_found", "invitation_revoked", "not_found", "organization_membership_conflict", "provider_link_expired", "unauthorized"];
6
+ };
7
+ export type AutharaContractAction = keyof typeof autharaActionErrorCodes;
8
+ export type AutharaContractErrorCode<Action extends AutharaContractAction> = (typeof autharaActionErrorCodes)[Action][number];
@@ -0,0 +1,42 @@
1
+ // Code generated from authara-core/contract/openapi.yaml; DO NOT EDIT.
2
+ export const autharaActionErrorCodes = {
3
+ login: [
4
+ "account_link_required",
5
+ "forbidden",
6
+ "internal_error",
7
+ "invalid_request",
8
+ "not_found",
9
+ "unauthorized",
10
+ ],
11
+ link: [
12
+ "auth_method_already_linked",
13
+ "forbidden",
14
+ "internal_error",
15
+ "invalid_request",
16
+ "not_found",
17
+ "recent_authentication_required",
18
+ "unauthorized",
19
+ ],
20
+ reauthenticate: [
21
+ "internal_error",
22
+ "invalid_authentication_challenge",
23
+ "invalid_request",
24
+ "not_found",
25
+ "unauthorized",
26
+ ],
27
+ recover: [
28
+ "auth_method_already_linked",
29
+ "forbidden",
30
+ "internal_error",
31
+ "invalid_request",
32
+ "invitation_already_accepted",
33
+ "invitation_email_mismatch",
34
+ "invitation_expired",
35
+ "invitation_not_found",
36
+ "invitation_revoked",
37
+ "not_found",
38
+ "organization_membership_conflict",
39
+ "provider_link_expired",
40
+ "unauthorized",
41
+ ],
42
+ };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
- export { AppleButton, type AppleButtonProps } from "./AppleButton.js";
2
- export { GoogleButton, type GoogleButtonProps } from "./GoogleButton.js";
1
+ export { AppleButton, AppleCredentialButton, type AppleButtonLabel, type AppleButtonProps, type AppleButtonVariant, type AppleCredentialButtonProps, } from "./AppleButton.js";
2
+ export { GoogleButton, GoogleCredentialButton, type GoogleButtonLabel, type GoogleButtonProps, type GoogleButtonVariant, type GoogleCredentialButtonProps, } from "./GoogleButton.js";
3
+ export { MicrosoftButton, MicrosoftCredentialButton, type MicrosoftButtonLabel, type MicrosoftButtonProps, type MicrosoftButtonVariant, type MicrosoftCredentialButtonProps, } from "./MicrosoftButton.js";
3
4
  export { AutharaProvider, type AutharaProviderProps } from "./context.js";
4
- export type { AppleLoginOptions, AutharaReactClient, GoogleLoginOptions, MaybePromise, } from "./contract.js";
5
- export { isAppleCancellation, isProviderUnavailable } from "./errors.js";
6
- export type { AppleAuthorization, GoogleCredential } from "./services.js";
5
+ export type { AutharaColorMode, ResolvedAutharaColorMode, } from "./color-mode.js";
6
+ export { autharaActionErrorCodes, type AutharaContractAction, type AutharaContractErrorCode, } from "./generated-error-codes.js";
7
+ export type { AppleLoginOptions, AppleProof, AutharaAction, AutharaAccountRecoveryLink, AutharaActionProps, AutharaActionSuccess, AutharaAudience, AutharaLinkSuccess, AutharaLoginSuccess, AutharaProviderName, AutharaRecoverySuccess, AutharaReauthenticationSuccess, AutharaReactClient, GoogleProof, GoogleLoginOptions, MicrosoftLoginOptions, MicrosoftProof, MaybePromise, } from "./contract.js";
8
+ export { AutharaButtonError, isAppleCancellation, isMicrosoftCancellation, isAutharaButtonError, isProviderUnavailable, type AutharaAuthenticationChallenge, type AutharaButtonErrorCode, type AutharaButtonErrorSource, type AutharaLocalErrorCode, type AutharaLinkErrorCode, type AutharaLoginErrorCode, type AutharaRecoveryErrorCode, type AutharaReauthenticationErrorCode, } from "./errors.js";
9
+ export type { AppleAuthorization, GoogleCredential, MicrosoftCredential, } from "./services.js";
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
- export { AppleButton } from "./AppleButton.js";
2
- export { GoogleButton } from "./GoogleButton.js";
1
+ export { AppleButton, AppleCredentialButton, } from "./AppleButton.js";
2
+ export { GoogleButton, GoogleCredentialButton, } from "./GoogleButton.js";
3
+ export { MicrosoftButton, MicrosoftCredentialButton, } from "./MicrosoftButton.js";
3
4
  export { AutharaProvider } from "./context.js";
4
- export { isAppleCancellation, isProviderUnavailable } from "./errors.js";
5
+ export { autharaActionErrorCodes, } from "./generated-error-codes.js";
6
+ export { AutharaButtonError, isAppleCancellation, isMicrosoftCancellation, isAutharaButtonError, isProviderUnavailable, } from "./errors.js";
@@ -1,29 +1,34 @@
1
- export type GoogleCredentialResponse = {
2
- credential?: string;
3
- select_by?: string;
4
- state?: string;
1
+ export type GoogleCodeResponse = {
2
+ code?: string;
3
+ error?: string;
4
+ error_description?: string;
5
+ };
6
+ export type GoogleCodeClient = {
7
+ requestCode(): void;
8
+ };
9
+ export type GoogleCodeClientConfiguration = {
10
+ client_id: string;
11
+ scope: string;
12
+ ux_mode: "popup";
13
+ select_account: boolean;
14
+ callback: (response: GoogleCodeResponse) => void;
15
+ error_callback: (error: {
16
+ type?: string;
17
+ }) => void;
5
18
  };
6
19
  export type GoogleButtonConfiguration = {
7
20
  type?: "standard" | "icon";
8
- theme?: "outline" | "filled_blue" | "filled_black";
21
+ theme?: "light" | "dark" | "neutral";
9
22
  size?: "large" | "medium" | "small";
10
23
  text?: "signin_with" | "signup_with" | "continue_with" | "signin";
11
24
  shape?: "rectangular" | "pill" | "circle" | "square";
12
25
  logo_alignment?: "left" | "center";
13
26
  width?: number;
14
- locale?: string;
15
- state?: string;
16
- click_listener?: () => void;
17
27
  };
18
28
  export type GoogleIdentity = {
19
29
  accounts: {
20
- id: {
21
- initialize(options: {
22
- client_id: string;
23
- nonce: string;
24
- callback: (response: GoogleCredentialResponse) => void;
25
- }): void;
26
- renderButton(parent: HTMLElement, options: GoogleButtonConfiguration): void;
30
+ oauth2: {
31
+ initCodeClient(options: GoogleCodeClientConfiguration): GoogleCodeClient;
27
32
  };
28
33
  };
29
34
  };
@@ -8,14 +8,17 @@ function appendScript(url, resolveGlobal, failureMessage) {
8
8
  return new Promise((resolve, reject) => {
9
9
  const existing = document.querySelector(`script[src="${url}"]`);
10
10
  const script = existing ?? document.createElement("script");
11
+ const failed = () => {
12
+ script.remove();
13
+ reject(new Error(failureMessage));
14
+ };
11
15
  const loaded = () => {
12
16
  const value = resolveGlobal();
13
17
  if (value)
14
18
  resolve(value);
15
19
  else
16
- reject(new Error(failureMessage));
20
+ failed();
17
21
  };
18
- const failed = () => reject(new Error(failureMessage));
19
22
  script.addEventListener("load", loaded, { once: true });
20
23
  script.addEventListener("error", failed, { once: true });
21
24
  if (!existing) {
@@ -26,7 +29,7 @@ function appendScript(url, resolveGlobal, failureMessage) {
26
29
  });
27
30
  }
28
31
  export function loadGoogleIdentity(locale) {
29
- if (window.google?.accounts?.id)
32
+ if (window.google?.accounts?.oauth2)
30
33
  return Promise.resolve(window.google);
31
34
  if (googlePromise) {
32
35
  if (locale !== googleLocale) {