@chipmobilesdk/rn-auth 0.2.1 → 0.3.1

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,73 +1,66 @@
1
- /**
2
- * Social provider routing (FR-002/FR-003, R3). Google and Apple are federated
3
- * inside the External ID tenant; the app presents the platform-correct action
4
- * and starts the user flow with a per-provider `domain_hint`.
5
- */
6
-
7
- import type {
8
- AuthConfig,
9
- DevicePlatform,
10
- ProviderConfig,
11
- ProviderId,
12
- } from '../config/types';
13
- import { AuthConfigError } from '../diagnostics/errors';
14
-
15
- /** Find the configured provider, ensuring it is enabled for the platform. */
16
- export function resolveProvider(
17
- config: AuthConfig,
18
- providerId: ProviderId,
19
- platform: DevicePlatform,
20
- ): ProviderConfig {
21
- const provider = config.providers.find(candidate => candidate.id === providerId);
22
- if (!provider) {
23
- throw new AuthConfigError(
24
- 'auth.error.configuration',
25
- `Provider "${providerId}" is not configured`,
26
- );
27
- }
28
- if (!provider.platforms.includes(platform)) {
29
- throw new AuthConfigError(
30
- 'auth.error.configuration',
31
- `Provider "${providerId}" is not enabled for platform "${platform}"`,
32
- );
33
- }
34
- if (provider.available === false) {
35
- throw new AuthConfigError(
36
- 'auth.error.configuration',
37
- `Provider "${providerId}" is marked unavailable`,
38
- );
39
- }
40
- return provider;
41
- }
42
-
43
- /** Build the OIDC additional parameters that route to the chosen IdP. */
44
- export function buildAdditionalParameters(
45
- provider: ProviderConfig,
46
- ): Record<string, string> {
47
- return { domain_hint: provider.domainHint };
48
- }
49
-
50
- /**
51
- * All providers to present on a given platform, in configuration array order
52
- * (FR-003/FR-004). Filtered to providers enabled for the platform and not marked
53
- * unavailable.
54
- */
55
- export function availableProvidersForPlatform(
56
- config: AuthConfig,
57
- platform: DevicePlatform,
58
- ): ProviderConfig[] {
59
- return config.providers.filter(
60
- provider => provider.platforms.includes(platform) && provider.available !== false,
61
- );
62
- }
63
-
64
- /**
65
- * The first available provider for a platform (UX-004, back-compat). Equals
66
- * `availableProvidersForPlatform(config, platform)[0]`.
67
- */
68
- export function defaultProviderForPlatform(
69
- config: AuthConfig,
70
- platform: DevicePlatform,
71
- ): ProviderConfig | undefined {
72
- return availableProvidersForPlatform(config, platform)[0];
73
- }
1
+ /**
2
+ * Social provider routing (FR-002/FR-003, R3). Google and Apple are federated
3
+ * inside the External ID tenant; the app presents the platform-correct action
4
+ * and starts the user flow with a per-provider `domain_hint`.
5
+ */
6
+
7
+ import type { AuthConfig, DevicePlatform, ProviderConfig, ProviderId } from '../config/types';
8
+ import { AuthConfigError } from '../diagnostics/errors';
9
+
10
+ /** Find the configured provider, ensuring it is enabled for the platform. */
11
+ export function resolveProvider(
12
+ config: AuthConfig,
13
+ providerId: ProviderId,
14
+ platform: DevicePlatform,
15
+ ): ProviderConfig {
16
+ const provider = config.providers.find(candidate => candidate.id === providerId);
17
+ if (!provider) {
18
+ throw new AuthConfigError(
19
+ 'auth.error.configuration',
20
+ `Provider "${providerId}" is not configured`,
21
+ );
22
+ }
23
+ if (!provider.platforms.includes(platform)) {
24
+ throw new AuthConfigError(
25
+ 'auth.error.configuration',
26
+ `Provider "${providerId}" is not enabled for platform "${platform}"`,
27
+ );
28
+ }
29
+ if (provider.available === false) {
30
+ throw new AuthConfigError(
31
+ 'auth.error.configuration',
32
+ `Provider "${providerId}" is marked unavailable`,
33
+ );
34
+ }
35
+ return provider;
36
+ }
37
+
38
+ /** Build the OIDC additional parameters that route to the chosen IdP. */
39
+ export function buildAdditionalParameters(provider: ProviderConfig): Record<string, string> {
40
+ return { domain_hint: provider.domainHint };
41
+ }
42
+
43
+ /**
44
+ * All providers to present on a given platform, in configuration array order
45
+ * (FR-003/FR-004). Filtered to providers enabled for the platform and not marked
46
+ * unavailable.
47
+ */
48
+ export function availableProvidersForPlatform(
49
+ config: AuthConfig,
50
+ platform: DevicePlatform,
51
+ ): ProviderConfig[] {
52
+ return config.providers.filter(
53
+ provider => provider.platforms.includes(platform) && provider.available !== false,
54
+ );
55
+ }
56
+
57
+ /**
58
+ * The first available provider for a platform (UX-004, back-compat). Equals
59
+ * `availableProvidersForPlatform(config, platform)[0]`.
60
+ */
61
+ export function defaultProviderForPlatform(
62
+ config: AuthConfig,
63
+ platform: DevicePlatform,
64
+ ): ProviderConfig | undefined {
65
+ return availableProvidersForPlatform(config, platform)[0];
66
+ }
@@ -1,47 +1,41 @@
1
- /**
2
- * React context boundary for the auth controller (LIB-002). Subscribes to the
3
- * controller and re-renders consumers on every state change.
4
- */
5
-
6
- import React, {
7
- createContext,
8
- useContext,
9
- useEffect,
10
- useMemo,
11
- useState,
12
- } from 'react';
13
- import type { Auth, AuthState } from '../config/types';
14
-
15
- interface AuthContextValue {
16
- auth: Auth;
17
- state: AuthState;
18
- }
19
-
20
- const AuthContext = createContext<AuthContextValue | null>(null);
21
-
22
- export interface AuthProviderProps {
23
- auth: Auth;
24
- children: React.ReactNode;
25
- }
26
-
27
- export function AuthProvider({ auth, children }: AuthProviderProps) {
28
- const [state, setState] = useState<AuthState>(() => auth.getState());
29
-
30
- useEffect(() => {
31
- // Sync immediately in case state changed between render and subscribe.
32
- setState(auth.getState());
33
- return auth.subscribe(setState);
34
- }, [auth]);
35
-
36
- const value = useMemo<AuthContextValue>(() => ({ auth, state }), [auth, state]);
37
-
38
- return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
39
- }
40
-
41
- export function useAuthContext(): AuthContextValue {
42
- const value = useContext(AuthContext);
43
- if (!value) {
44
- throw new Error('useAuth must be used within an <AuthProvider>.');
45
- }
46
- return value;
47
- }
1
+ /**
2
+ * React context boundary for the auth controller (LIB-002). Subscribes to the
3
+ * controller and re-renders consumers on every state change.
4
+ */
5
+
6
+ import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
7
+ import type { Auth, AuthState } from '../config/types';
8
+
9
+ interface AuthContextValue {
10
+ auth: Auth;
11
+ state: AuthState;
12
+ }
13
+
14
+ const AuthContext = createContext<AuthContextValue | null>(null);
15
+
16
+ export interface AuthProviderProps {
17
+ auth: Auth;
18
+ children: React.ReactNode;
19
+ }
20
+
21
+ export function AuthProvider({ auth, children }: AuthProviderProps) {
22
+ const [state, setState] = useState<AuthState>(() => auth.getState());
23
+
24
+ useEffect(() => {
25
+ // Sync immediately in case state changed between render and subscribe.
26
+ setState(auth.getState());
27
+ return auth.subscribe(setState);
28
+ }, [auth]);
29
+
30
+ const value = useMemo<AuthContextValue>(() => ({ auth, state }), [auth, state]);
31
+
32
+ return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
33
+ }
34
+
35
+ export function useAuthContext(): AuthContextValue {
36
+ const value = useContext(AuthContext);
37
+ if (!value) {
38
+ throw new Error('useAuth must be used within an <AuthProvider>.');
39
+ }
40
+ return value;
41
+ }
@@ -1,90 +1,86 @@
1
- /**
2
- * Public hooks (LIB-002). All read from the AuthProvider context so consumers
3
- * re-render on state changes.
4
- */
5
-
6
- import { useCallback, useState } from 'react';
7
- import { useAuthContext } from './AuthProvider';
8
- import type {
9
- AccessTier,
10
- AccessTokenResult,
11
- AuthState,
12
- PremiumGateResult,
13
- Profile,
14
- ProviderConfig,
15
- ProviderId,
16
- } from '../config/types';
17
- import { failClosedTier } from '../access/accessTier';
18
-
19
- export interface UseAuthResult {
20
- state: AuthState;
21
- signIn(providerId: ProviderId): Promise<AuthState>;
22
- signOut(): Promise<void>;
23
- signOutGlobal(): Promise<void>;
24
- restore(): Promise<AuthState>;
25
- requirePremium(): PremiumGateResult;
26
- }
27
-
28
- export function useAuth(): UseAuthResult {
29
- const { auth, state } = useAuthContext();
30
- return {
31
- state,
32
- signIn: useCallback((providerId: ProviderId) => auth.signIn(providerId), [auth]),
33
- signOut: useCallback(() => auth.signOut(), [auth]),
34
- signOutGlobal: useCallback(() => auth.signOutGlobal(), [auth]),
35
- restore: useCallback(() => auth.restore(), [auth]),
36
- requirePremium: useCallback(() => auth.requirePremium(), [auth]),
37
- };
38
- }
39
-
40
- export function useProfile(): Profile | undefined {
41
- const { state } = useAuthContext();
42
- return state.profile;
43
- }
44
-
45
- export function useAccessTier(): AccessTier {
46
- const { state } = useAuthContext();
47
- return state.accessTier ?? failClosedTier();
48
- }
49
-
50
- /** The first provider to present on the current platform (UX-004), or undefined. */
51
- export function useSignInProvider(): ProviderConfig | undefined {
52
- const { auth } = useAuthContext();
53
- return auth.getPlatformProvider();
54
- }
55
-
56
- /** All available providers for the current platform, in configuration order (FR-003/FR-004). */
57
- export function useSignInProviders(): ProviderConfig[] {
58
- const { auth } = useAuthContext();
59
- return auth.getPlatformProviders();
60
- }
61
-
62
- export type UseAccessTokenStatus =
63
- | 'idle'
64
- | 'loading'
65
- | 'success'
66
- | 'denied'
67
- | 'unavailable'
68
- | 'error';
69
-
70
- export interface UseAccessTokenResult {
71
- status: UseAccessTokenStatus;
72
- token?: string;
73
- request(): Promise<AccessTokenResult>;
74
- }
75
-
76
- export function useAccessToken(resourceKey: string): UseAccessTokenResult {
77
- const { auth } = useAuthContext();
78
- const [status, setStatus] = useState<UseAccessTokenStatus>('idle');
79
- const [token, setToken] = useState<string | undefined>(undefined);
80
-
81
- const request = useCallback(async () => {
82
- setStatus('loading');
83
- const result = await auth.requestAccessToken(resourceKey);
84
- setStatus(result.status);
85
- setToken(result.token);
86
- return result;
87
- }, [auth, resourceKey]);
88
-
89
- return { status, token, request };
90
- }
1
+ /**
2
+ * Public hooks (LIB-002). All read from the AuthProvider context so consumers
3
+ * re-render on state changes.
4
+ */
5
+
6
+ import { useCallback, useState } from 'react';
7
+ import { useAuthContext } from './AuthProvider';
8
+ import type {
9
+ AccessTier,
10
+ AccessTokenResult,
11
+ AuthState,
12
+ GlobalSignOutResult,
13
+ PremiumGateResult,
14
+ Profile,
15
+ ProviderConfig,
16
+ ProviderId,
17
+ } from '../config/types';
18
+ import { failClosedTier } from '../access/accessTier';
19
+
20
+ export interface UseAuthResult {
21
+ state: AuthState;
22
+ signIn(providerId: ProviderId): Promise<AuthState>;
23
+ signOut(): Promise<void>;
24
+ signOutGlobal(): Promise<GlobalSignOutResult>;
25
+ restore(): Promise<AuthState>;
26
+ requirePremium(): PremiumGateResult;
27
+ }
28
+
29
+ export function useAuth(): UseAuthResult {
30
+ const { auth, state } = useAuthContext();
31
+ return {
32
+ state,
33
+ signIn: useCallback((providerId: ProviderId) => auth.signIn(providerId), [auth]),
34
+ signOut: useCallback(() => auth.signOut(), [auth]),
35
+ signOutGlobal: useCallback(() => auth.signOutGlobal(), [auth]),
36
+ restore: useCallback(() => auth.restore(), [auth]),
37
+ requirePremium: useCallback(() => auth.requirePremium(), [auth]),
38
+ };
39
+ }
40
+
41
+ export function useProfile(): Profile | undefined {
42
+ const { state } = useAuthContext();
43
+ return state.profile;
44
+ }
45
+
46
+ export function useAccessTier(): AccessTier {
47
+ const { state } = useAuthContext();
48
+ return state.accessTier ?? failClosedTier();
49
+ }
50
+
51
+ /** The first provider to present on the current platform (UX-004), or undefined. */
52
+ export function useSignInProvider(): ProviderConfig | undefined {
53
+ const { auth } = useAuthContext();
54
+ return auth.getPlatformProvider();
55
+ }
56
+
57
+ /** All available providers for the current platform, in configuration order (FR-003/FR-004). */
58
+ export function useSignInProviders(): ProviderConfig[] {
59
+ const { auth } = useAuthContext();
60
+ return auth.getPlatformProviders();
61
+ }
62
+
63
+ export type UseAccessTokenStatus =
64
+ 'idle' | 'loading' | 'success' | 'denied' | 'unavailable' | 'error';
65
+
66
+ export interface UseAccessTokenResult {
67
+ status: UseAccessTokenStatus;
68
+ token?: string;
69
+ request(): Promise<AccessTokenResult>;
70
+ }
71
+
72
+ export function useAccessToken(resourceKey: string): UseAccessTokenResult {
73
+ const { auth } = useAuthContext();
74
+ const [status, setStatus] = useState<UseAccessTokenStatus>('idle');
75
+ const [token, setToken] = useState<string | undefined>(undefined);
76
+
77
+ const request = useCallback(async () => {
78
+ setStatus('loading');
79
+ const result = await auth.requestAccessToken(resourceKey);
80
+ setStatus(result.status);
81
+ setToken(result.token);
82
+ return result;
83
+ }, [auth, resourceKey]);
84
+
85
+ return { status, token, request };
86
+ }