rystem.authentication.social.client 0.5.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.
Files changed (141) hide show
  1. package/README.md +1903 -0
  2. package/lib/buttons/CreateSocialButton.d.ts +15 -0
  3. package/lib/buttons/CreateSocialButton.js +158 -0
  4. package/lib/buttons/SocialLoginButtons.d.ts +2 -0
  5. package/lib/buttons/SocialLoginButtons.js +22 -0
  6. package/lib/buttons/SocialLogoutButton.d.ts +3 -0
  7. package/lib/buttons/SocialLogoutButton.js +11 -0
  8. package/lib/buttons/graphics/AmazonLoginButton.d.ts +1 -0
  9. package/lib/buttons/graphics/AmazonLoginButton.js +10 -0
  10. package/lib/buttons/graphics/AppleLoginButton.d.ts +1 -0
  11. package/lib/buttons/graphics/AppleLoginButton.js +17 -0
  12. package/lib/buttons/graphics/BufferLoginButton.d.ts +1 -0
  13. package/lib/buttons/graphics/BufferLoginButton.js +17 -0
  14. package/lib/buttons/graphics/DiscordLoginButton.d.ts +1 -0
  15. package/lib/buttons/graphics/DiscordLoginButton.js +17 -0
  16. package/lib/buttons/graphics/FacebookLoginButton.d.ts +1 -0
  17. package/lib/buttons/graphics/FacebookLoginButton.js +10 -0
  18. package/lib/buttons/graphics/GithubLoginButton.d.ts +1 -0
  19. package/lib/buttons/graphics/GithubLoginButton.js +10 -0
  20. package/lib/buttons/graphics/GoogleLoginButton.d.ts +1 -0
  21. package/lib/buttons/graphics/GoogleLoginButton.js +10 -0
  22. package/lib/buttons/graphics/InstagramLoginButton.d.ts +1 -0
  23. package/lib/buttons/graphics/InstagramLoginButton.js +10 -0
  24. package/lib/buttons/graphics/LinkedInLoginButton.d.ts +1 -0
  25. package/lib/buttons/graphics/LinkedInLoginButton.js +10 -0
  26. package/lib/buttons/graphics/MetamaskLoginButton.d.ts +1 -0
  27. package/lib/buttons/graphics/MetamaskLoginButton.js +25 -0
  28. package/lib/buttons/graphics/MicrosoftLoginButton.d.ts +1 -0
  29. package/lib/buttons/graphics/MicrosoftLoginButton.js +10 -0
  30. package/lib/buttons/graphics/OktaLoginButton.d.ts +1 -0
  31. package/lib/buttons/graphics/OktaLoginButton.js +17 -0
  32. package/lib/buttons/graphics/PinterestLoginButton.d.ts +1 -0
  33. package/lib/buttons/graphics/PinterestLoginButton.js +10 -0
  34. package/lib/buttons/graphics/SlackLoginButton.d.ts +1 -0
  35. package/lib/buttons/graphics/SlackLoginButton.js +17 -0
  36. package/lib/buttons/graphics/SocialButtonStyle.d.ts +8 -0
  37. package/lib/buttons/graphics/SocialButtonStyle.js +2 -0
  38. package/lib/buttons/graphics/SocialLoginButton.d.ts +2 -0
  39. package/lib/buttons/graphics/SocialLoginButton.js +46 -0
  40. package/lib/buttons/graphics/TelegramLoginButton.d.ts +1 -0
  41. package/lib/buttons/graphics/TelegramLoginButton.js +17 -0
  42. package/lib/buttons/graphics/TikTokLoginButton.d.ts +1 -0
  43. package/lib/buttons/graphics/TikTokLoginButton.js +10 -0
  44. package/lib/buttons/graphics/XLoginButton.d.ts +1 -0
  45. package/lib/buttons/graphics/XLoginButton.js +10 -0
  46. package/lib/buttons/graphics/YahooLoginButton.d.ts +1 -0
  47. package/lib/buttons/graphics/YahooLoginButton.js +17 -0
  48. package/lib/buttons/graphics/ZaloLoginButton.d.ts +1 -0
  49. package/lib/buttons/graphics/ZaloLoginButton.js +17 -0
  50. package/lib/buttons/singles/AmazonButton.d.ts +2 -0
  51. package/lib/buttons/singles/AmazonButton.js +33 -0
  52. package/lib/buttons/singles/FacebookButton.d.ts +2 -0
  53. package/lib/buttons/singles/FacebookButton.js +55 -0
  54. package/lib/buttons/singles/GitHubButton.d.ts +2 -0
  55. package/lib/buttons/singles/GitHubButton.js +19 -0
  56. package/lib/buttons/singles/GoogleButton.d.ts +2 -0
  57. package/lib/buttons/singles/GoogleButton.js +44 -0
  58. package/lib/buttons/singles/InstagramButton.d.ts +2 -0
  59. package/lib/buttons/singles/InstagramButton.js +21 -0
  60. package/lib/buttons/singles/LinkedinButton.d.ts +2 -0
  61. package/lib/buttons/singles/LinkedinButton.js +23 -0
  62. package/lib/buttons/singles/MicrosoftButton.d.ts +2 -0
  63. package/lib/buttons/singles/MicrosoftButton.js +68 -0
  64. package/lib/buttons/singles/PinterestButton.d.ts +2 -0
  65. package/lib/buttons/singles/PinterestButton.js +22 -0
  66. package/lib/buttons/singles/TikTokButton.d.ts +2 -0
  67. package/lib/buttons/singles/TikTokButton.js +18 -0
  68. package/lib/buttons/singles/XButton.d.ts +2 -0
  69. package/lib/buttons/singles/XButton.js +24 -0
  70. package/lib/components/BrandIcons.d.ts +64 -0
  71. package/lib/components/BrandIcons.js +76 -0
  72. package/lib/components/ModernSocialButton.d.ts +21 -0
  73. package/lib/components/ModernSocialButton.js +23 -0
  74. package/lib/context/SocialLoginContext.d.ts +4 -0
  75. package/lib/context/SocialLoginContext.js +10 -0
  76. package/lib/context/SocialLoginWrapper.d.ts +3 -0
  77. package/lib/context/SocialLoginWrapper.js +137 -0
  78. package/lib/hooks/removeSocialLogin.d.ts +1 -0
  79. package/lib/hooks/removeSocialLogin.js +14 -0
  80. package/lib/hooks/useSocialToken.d.ts +2 -0
  81. package/lib/hooks/useSocialToken.js +21 -0
  82. package/lib/hooks/useSocialUser.d.ts +2 -0
  83. package/lib/hooks/useSocialUser.js +30 -0
  84. package/lib/index.d.ts +47 -0
  85. package/lib/index.js +90 -0
  86. package/lib/models/SocialButtonProps.d.ts +3 -0
  87. package/lib/models/SocialButtonProps.js +2 -0
  88. package/lib/models/SocialButtonsProps.d.ts +4 -0
  89. package/lib/models/SocialButtonsProps.js +2 -0
  90. package/lib/models/SocialToken.d.ts +6 -0
  91. package/lib/models/SocialToken.js +2 -0
  92. package/lib/models/SocialUser.d.ts +5 -0
  93. package/lib/models/SocialUser.js +2 -0
  94. package/lib/models/Token.d.ts +6 -0
  95. package/lib/models/Token.js +2 -0
  96. package/lib/models/setup/LoginMode.d.ts +13 -0
  97. package/lib/models/setup/LoginMode.js +17 -0
  98. package/lib/models/setup/PlatformConfig.d.ts +45 -0
  99. package/lib/models/setup/PlatformConfig.js +19 -0
  100. package/lib/models/setup/PlatformType.d.ts +21 -0
  101. package/lib/models/setup/PlatformType.js +25 -0
  102. package/lib/models/setup/ProviderType.d.ts +13 -0
  103. package/lib/models/setup/ProviderType.js +17 -0
  104. package/lib/models/setup/SocialLoginErrorResponse.d.ts +6 -0
  105. package/lib/models/setup/SocialLoginErrorResponse.js +2 -0
  106. package/lib/models/setup/SocialLoginSettings.d.ts +66 -0
  107. package/lib/models/setup/SocialLoginSettings.js +2 -0
  108. package/lib/models/setup/SocialParameter.d.ts +3 -0
  109. package/lib/models/setup/SocialParameter.js +2 -0
  110. package/lib/services/IRoutingService.d.ts +123 -0
  111. package/lib/services/IRoutingService.js +2 -0
  112. package/lib/services/IStorageService.d.ts +33 -0
  113. package/lib/services/IStorageService.js +2 -0
  114. package/lib/services/LocalStorageService.d.ts +32 -0
  115. package/lib/services/LocalStorageService.js +93 -0
  116. package/lib/services/MockRoutingService.example.d.ts +96 -0
  117. package/lib/services/MockRoutingService.example.js +153 -0
  118. package/lib/services/NextAppRouterRoutingService.example.d.ts +75 -0
  119. package/lib/services/NextAppRouterRoutingService.example.js +128 -0
  120. package/lib/services/PkceStorageService.d.ts +55 -0
  121. package/lib/services/PkceStorageService.js +103 -0
  122. package/lib/services/ReactRouterRoutingService.example.d.ts +69 -0
  123. package/lib/services/ReactRouterRoutingService.example.js +121 -0
  124. package/lib/services/TokenStorageService.d.ts +34 -0
  125. package/lib/services/TokenStorageService.js +90 -0
  126. package/lib/services/UserStorageService.d.ts +29 -0
  127. package/lib/services/UserStorageService.js +56 -0
  128. package/lib/services/WindowRoutingService.d.ts +74 -0
  129. package/lib/services/WindowRoutingService.js +118 -0
  130. package/lib/setup/SocialLoginManager.d.ts +12 -0
  131. package/lib/setup/SocialLoginManager.js +106 -0
  132. package/lib/setup/getSocialLoginSettings.d.ts +2 -0
  133. package/lib/setup/getSocialLoginSettings.js +8 -0
  134. package/lib/setup/setupSocialLogin.d.ts +2 -0
  135. package/lib/setup/setupSocialLogin.js +62 -0
  136. package/lib/styles/SocialButton.css +365 -0
  137. package/lib/utils/pkce.d.ts +18 -0
  138. package/lib/utils/pkce.js +44 -0
  139. package/lib/utils/platform.d.ts +30 -0
  140. package/lib/utils/platform.js +103 -0
  141. package/package.json +45 -0
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ /**
3
+ * Unified Routing Service for Next.js App Router (v13+)
4
+ *
5
+ * This service handles both URL parameter reading and navigation for Next.js with App Router.
6
+ * Copy this file to your project and remove the `.example` extension.
7
+ *
8
+ * IMPORTANT: This must be used in Client Components ('use client')
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * 'use client';
13
+ *
14
+ * import { NextAppRouterRoutingService } from './NextAppRouterRoutingService';
15
+ * import { useRouter, usePathname, useSearchParams } from 'next/navigation';
16
+ *
17
+ * const routingService = new NextAppRouterRoutingService();
18
+ *
19
+ * setupSocialLogin(x => {
20
+ * x.routingService = routingService;
21
+ * });
22
+ *
23
+ * export default function LoginPage() {
24
+ * const router = useRouter();
25
+ * const pathname = usePathname();
26
+ * const searchParams = useSearchParams();
27
+ *
28
+ * useEffect(() => {
29
+ * // Single initialization with all hooks
30
+ * routingService.initialize(router, pathname, searchParams);
31
+ * }, [router, pathname, searchParams]);
32
+ *
33
+ * return <div>Your login page</div>;
34
+ * }
35
+ * ```
36
+ */
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.NextAppRouterRoutingService = void 0;
39
+ /**
40
+ * Routing Service for Next.js App Router (v13+)
41
+ * Uses useRouter, usePathname, and useSearchParams from next/navigation
42
+ *
43
+ * NOTE: Only works in Client Components ('use client' directive required)
44
+ */
45
+ class NextAppRouterRoutingService {
46
+ router = null;
47
+ pathname = null;
48
+ searchParams = null;
49
+ /**
50
+ * Initialize with Next.js navigation hooks
51
+ * MUST be called inside a Client Component ('use client')
52
+ *
53
+ * @param router - The router from useRouter() hook
54
+ * @param pathname - The pathname from usePathname() hook
55
+ * @param searchParams - The searchParams from useSearchParams() hook
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * 'use client';
60
+ *
61
+ * const router = useRouter();
62
+ * const pathname = usePathname();
63
+ * const searchParams = useSearchParams();
64
+ *
65
+ * useEffect(() => {
66
+ * routingService.initialize(router, pathname, searchParams);
67
+ * }, [router, pathname, searchParams]);
68
+ * ```
69
+ */
70
+ initialize(router, pathname, searchParams) {
71
+ this.router = router;
72
+ this.pathname = pathname;
73
+ this.searchParams = searchParams;
74
+ }
75
+ // ===== URL Parameter Reading =====
76
+ getSearchParam(key) {
77
+ if (!this.searchParams) {
78
+ console.warn('NextAppRouterRoutingService not initialized. Call initialize() with Next.js hooks.');
79
+ return null;
80
+ }
81
+ return this.searchParams.get(key);
82
+ }
83
+ getAllSearchParams() {
84
+ if (!this.searchParams) {
85
+ console.warn('NextAppRouterRoutingService not initialized. Call initialize() with Next.js hooks.');
86
+ return new URLSearchParams();
87
+ }
88
+ return this.searchParams;
89
+ }
90
+ // ===== Navigation Operations =====
91
+ getCurrentPath() {
92
+ if (!this.pathname) {
93
+ console.warn('NextAppRouterRoutingService not initialized. Falling back to window.location.');
94
+ return window.location.pathname + window.location.search;
95
+ }
96
+ const search = this.searchParams?.toString();
97
+ return search ? `${this.pathname}?${search}` : this.pathname;
98
+ }
99
+ navigateTo(url) {
100
+ // External OAuth redirects (https://...) must use window.location
101
+ if (url.startsWith('http://') || url.startsWith('https://')) {
102
+ console.log('🌐 [NextJS] External OAuth redirect, using window.location:', url);
103
+ window.location.href = url;
104
+ }
105
+ else if (this.router) {
106
+ console.log('🔄 [NextJS] Internal navigation:', url);
107
+ this.router.push(url);
108
+ }
109
+ else {
110
+ console.warn('NextAppRouterRoutingService not initialized. Using window.location.');
111
+ window.location.href = url;
112
+ }
113
+ }
114
+ navigateReplace(path) {
115
+ if (this.router) {
116
+ console.log('🔄 [NextJS] Replacing URL:', path);
117
+ this.router.replace(path);
118
+ }
119
+ else {
120
+ console.warn('NextAppRouterRoutingService not initialized. Using window.history.');
121
+ window.history.replaceState({}, '', path);
122
+ }
123
+ }
124
+ openPopup(url, name, features) {
125
+ return window.open(url, name, features);
126
+ }
127
+ }
128
+ exports.NextAppRouterRoutingService = NextAppRouterRoutingService;
@@ -0,0 +1,55 @@
1
+ import { IStorageService } from "./IStorageService";
2
+ /**
3
+ * PKCE storage service (decorator pattern)
4
+ * Adds domain logic (key prefixes, validation) on top of generic storage
5
+ */
6
+ export declare class PkceStorageService {
7
+ private storage;
8
+ private readonly prefix;
9
+ constructor(storage: IStorageService);
10
+ /**
11
+ * Store PKCE code verifier for a provider
12
+ * @param provider Provider name (microsoft, google, etc.)
13
+ * @param codeVerifier PKCE code verifier (43+ chars, Base64URL)
14
+ */
15
+ storeCodeVerifier(provider: string, codeVerifier: string): void;
16
+ /**
17
+ * Get PKCE code verifier for a provider
18
+ * @param provider Provider name
19
+ * @returns Code verifier or null if not found/invalid
20
+ */
21
+ getCodeVerifier(provider: string): string | null;
22
+ /**
23
+ * Get and remove PKCE code verifier (consume once)
24
+ * Used during token exchange to retrieve and cleanup
25
+ */
26
+ getAndRemoveCodeVerifier(provider: string): string | null;
27
+ /**
28
+ * Remove PKCE code verifier for a provider
29
+ */
30
+ removeCodeVerifier(provider: string): void;
31
+ /**
32
+ * Check if PKCE code verifier exists for a provider
33
+ */
34
+ hasCodeVerifier(provider: string): boolean;
35
+ /**
36
+ * Store PKCE code challenge for a provider (optional, for debugging)
37
+ */
38
+ storeCodeChallenge(provider: string, codeChallenge: string): void;
39
+ /**
40
+ * Get PKCE code challenge for a provider
41
+ */
42
+ getCodeChallenge(provider: string): string | null;
43
+ /**
44
+ * Remove PKCE code challenge for a provider
45
+ */
46
+ removeCodeChallenge(provider: string): void;
47
+ /**
48
+ * Clear all PKCE data for a provider
49
+ */
50
+ clearAll(provider: string): void;
51
+ /**
52
+ * Build storage key with prefix
53
+ */
54
+ private getKey;
55
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PkceStorageService = void 0;
4
+ /**
5
+ * PKCE storage service (decorator pattern)
6
+ * Adds domain logic (key prefixes, validation) on top of generic storage
7
+ */
8
+ class PkceStorageService {
9
+ storage;
10
+ prefix = 'rystem_pkce_';
11
+ constructor(storage) {
12
+ this.storage = storage;
13
+ }
14
+ /**
15
+ * Store PKCE code verifier for a provider
16
+ * @param provider Provider name (microsoft, google, etc.)
17
+ * @param codeVerifier PKCE code verifier (43+ chars, Base64URL)
18
+ */
19
+ storeCodeVerifier(provider, codeVerifier) {
20
+ if (!codeVerifier || codeVerifier.length < 43) {
21
+ console.warn(`PkceStorageService: Invalid code verifier for ${provider}`);
22
+ return;
23
+ }
24
+ const key = this.getKey(provider, 'verifier');
25
+ this.storage.set(key, codeVerifier);
26
+ }
27
+ /**
28
+ * Get PKCE code verifier for a provider
29
+ * @param provider Provider name
30
+ * @returns Code verifier or null if not found/invalid
31
+ */
32
+ getCodeVerifier(provider) {
33
+ const key = this.getKey(provider, 'verifier');
34
+ const value = this.storage.get(key);
35
+ // Validation: PKCE verifier must be at least 43 characters (RFC 7636)
36
+ if (value && value.length < 43) {
37
+ console.warn(`PkceStorageService: Invalid code verifier for ${provider} (length: ${value.length})`);
38
+ this.removeCodeVerifier(provider);
39
+ return null;
40
+ }
41
+ return value;
42
+ }
43
+ /**
44
+ * Get and remove PKCE code verifier (consume once)
45
+ * Used during token exchange to retrieve and cleanup
46
+ */
47
+ getAndRemoveCodeVerifier(provider) {
48
+ const verifier = this.getCodeVerifier(provider);
49
+ if (verifier) {
50
+ this.removeCodeVerifier(provider);
51
+ }
52
+ return verifier;
53
+ }
54
+ /**
55
+ * Remove PKCE code verifier for a provider
56
+ */
57
+ removeCodeVerifier(provider) {
58
+ const key = this.getKey(provider, 'verifier');
59
+ this.storage.remove(key);
60
+ }
61
+ /**
62
+ * Check if PKCE code verifier exists for a provider
63
+ */
64
+ hasCodeVerifier(provider) {
65
+ const key = this.getKey(provider, 'verifier');
66
+ return this.storage.has(key);
67
+ }
68
+ /**
69
+ * Store PKCE code challenge for a provider (optional, for debugging)
70
+ */
71
+ storeCodeChallenge(provider, codeChallenge) {
72
+ const key = this.getKey(provider, 'challenge');
73
+ this.storage.set(key, codeChallenge);
74
+ }
75
+ /**
76
+ * Get PKCE code challenge for a provider
77
+ */
78
+ getCodeChallenge(provider) {
79
+ const key = this.getKey(provider, 'challenge');
80
+ return this.storage.get(key);
81
+ }
82
+ /**
83
+ * Remove PKCE code challenge for a provider
84
+ */
85
+ removeCodeChallenge(provider) {
86
+ const key = this.getKey(provider, 'challenge');
87
+ this.storage.remove(key);
88
+ }
89
+ /**
90
+ * Clear all PKCE data for a provider
91
+ */
92
+ clearAll(provider) {
93
+ this.removeCodeVerifier(provider);
94
+ this.removeCodeChallenge(provider);
95
+ }
96
+ /**
97
+ * Build storage key with prefix
98
+ */
99
+ getKey(provider, type) {
100
+ return `${this.prefix}${provider}_${type}`;
101
+ }
102
+ }
103
+ exports.PkceStorageService = PkceStorageService;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Unified Routing Service for React Router v6+
3
+ *
4
+ * This service handles both URL parameter reading and navigation for React Router.
5
+ * Copy this file to your project and remove the `.example` extension.
6
+ *
7
+ * IMPORTANT: Must be initialized inside a React component with routing context.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { ReactRouterRoutingService } from './ReactRouterRoutingService';
12
+ * import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
13
+ *
14
+ * const routingService = new ReactRouterRoutingService();
15
+ *
16
+ * setupSocialLogin(x => {
17
+ * x.routingService = routingService;
18
+ * });
19
+ *
20
+ * function App() {
21
+ * const [searchParams] = useSearchParams();
22
+ * const navigate = useNavigate();
23
+ * const location = useLocation();
24
+ *
25
+ * useEffect(() => {
26
+ * // Single initialization with all hooks
27
+ * routingService.initialize(() => searchParams, navigate, location);
28
+ * }, [searchParams, navigate, location]);
29
+ *
30
+ * return <div>Your app</div>;
31
+ * }
32
+ * ```
33
+ */
34
+ import type { IRoutingService } from './IRoutingService';
35
+ /**
36
+ * Routing Service for React Router v6+
37
+ * Uses useSearchParams, useNavigate, and useLocation hooks
38
+ */
39
+ export declare class ReactRouterRoutingService implements IRoutingService {
40
+ private searchParamsGetter;
41
+ private navigateFunc;
42
+ private location;
43
+ /**
44
+ * Initialize with React Router hooks
45
+ * MUST be called inside a React component with routing context
46
+ *
47
+ * @param searchParamsGetter - Function that returns URLSearchParams from useSearchParams()
48
+ * @param navigateFunc - The navigate function from useNavigate()
49
+ * @param location - The location object from useLocation()
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const [searchParams] = useSearchParams();
54
+ * const navigate = useNavigate();
55
+ * const location = useLocation();
56
+ *
57
+ * useEffect(() => {
58
+ * routingService.initialize(() => searchParams, navigate, location);
59
+ * }, [searchParams, navigate, location]);
60
+ * ```
61
+ */
62
+ initialize(searchParamsGetter: () => URLSearchParams, navigateFunc: (to: string, options?: any) => void, location: any): void;
63
+ getSearchParam(key: string): string | null;
64
+ getAllSearchParams(): URLSearchParams;
65
+ getCurrentPath(): string;
66
+ navigateTo(url: string): void;
67
+ navigateReplace(path: string): void;
68
+ openPopup(url: string, name: string, features: string): Window | null;
69
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /**
3
+ * Unified Routing Service for React Router v6+
4
+ *
5
+ * This service handles both URL parameter reading and navigation for React Router.
6
+ * Copy this file to your project and remove the `.example` extension.
7
+ *
8
+ * IMPORTANT: Must be initialized inside a React component with routing context.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { ReactRouterRoutingService } from './ReactRouterRoutingService';
13
+ * import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
14
+ *
15
+ * const routingService = new ReactRouterRoutingService();
16
+ *
17
+ * setupSocialLogin(x => {
18
+ * x.routingService = routingService;
19
+ * });
20
+ *
21
+ * function App() {
22
+ * const [searchParams] = useSearchParams();
23
+ * const navigate = useNavigate();
24
+ * const location = useLocation();
25
+ *
26
+ * useEffect(() => {
27
+ * // Single initialization with all hooks
28
+ * routingService.initialize(() => searchParams, navigate, location);
29
+ * }, [searchParams, navigate, location]);
30
+ *
31
+ * return <div>Your app</div>;
32
+ * }
33
+ * ```
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ReactRouterRoutingService = void 0;
37
+ /**
38
+ * Routing Service for React Router v6+
39
+ * Uses useSearchParams, useNavigate, and useLocation hooks
40
+ */
41
+ class ReactRouterRoutingService {
42
+ searchParamsGetter = null;
43
+ navigateFunc = null;
44
+ location = null;
45
+ /**
46
+ * Initialize with React Router hooks
47
+ * MUST be called inside a React component with routing context
48
+ *
49
+ * @param searchParamsGetter - Function that returns URLSearchParams from useSearchParams()
50
+ * @param navigateFunc - The navigate function from useNavigate()
51
+ * @param location - The location object from useLocation()
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const [searchParams] = useSearchParams();
56
+ * const navigate = useNavigate();
57
+ * const location = useLocation();
58
+ *
59
+ * useEffect(() => {
60
+ * routingService.initialize(() => searchParams, navigate, location);
61
+ * }, [searchParams, navigate, location]);
62
+ * ```
63
+ */
64
+ initialize(searchParamsGetter, navigateFunc, location) {
65
+ this.searchParamsGetter = searchParamsGetter;
66
+ this.navigateFunc = navigateFunc;
67
+ this.location = location;
68
+ }
69
+ // ===== URL Parameter Reading =====
70
+ getSearchParam(key) {
71
+ if (!this.searchParamsGetter) {
72
+ console.warn('ReactRouterRoutingService not initialized. Call initialize() with React Router hooks.');
73
+ return null;
74
+ }
75
+ return this.searchParamsGetter().get(key);
76
+ }
77
+ getAllSearchParams() {
78
+ if (!this.searchParamsGetter) {
79
+ console.warn('ReactRouterRoutingService not initialized. Call initialize() with React Router hooks.');
80
+ return new URLSearchParams();
81
+ }
82
+ return this.searchParamsGetter();
83
+ }
84
+ // ===== Navigation Operations =====
85
+ getCurrentPath() {
86
+ if (!this.location) {
87
+ console.warn('ReactRouterRoutingService not initialized. Falling back to window.location.');
88
+ return window.location.pathname + window.location.search;
89
+ }
90
+ return this.location.pathname + this.location.search;
91
+ }
92
+ navigateTo(url) {
93
+ // External OAuth redirects (https://...) must use window.location
94
+ if (url.startsWith('http://') || url.startsWith('https://')) {
95
+ console.log('🌐 [ReactRouter] External OAuth redirect, using window.location:', url);
96
+ window.location.href = url;
97
+ }
98
+ else if (this.navigateFunc) {
99
+ console.log('🔄 [ReactRouter] Internal navigation:', url);
100
+ this.navigateFunc(url);
101
+ }
102
+ else {
103
+ console.warn('ReactRouterRoutingService not initialized. Using window.location.');
104
+ window.location.href = url;
105
+ }
106
+ }
107
+ navigateReplace(path) {
108
+ if (this.navigateFunc) {
109
+ console.log('🔄 [ReactRouter] Replacing URL:', path);
110
+ this.navigateFunc(path, { replace: true });
111
+ }
112
+ else {
113
+ console.warn('ReactRouterRoutingService not initialized. Using window.history.');
114
+ window.history.replaceState({}, '', path);
115
+ }
116
+ }
117
+ openPopup(url, name, features) {
118
+ return window.open(url, name, features);
119
+ }
120
+ }
121
+ exports.ReactRouterRoutingService = ReactRouterRoutingService;
@@ -0,0 +1,34 @@
1
+ import { IStorageService } from "./IStorageService";
2
+ import { Token } from "../models/Token";
3
+ /**
4
+ * Token storage service (decorator pattern)
5
+ * Adds domain logic (expiry check, JSON serialization) on top of generic storage
6
+ */
7
+ export declare class TokenStorageService {
8
+ private storage;
9
+ private readonly tokenKey;
10
+ private readonly expiryKey;
11
+ constructor(storage: IStorageService);
12
+ /**
13
+ * Save social authentication token
14
+ * @param token Token with expiry information (Date)
15
+ */
16
+ saveToken(token: Token): void;
17
+ /**
18
+ * Get social authentication token
19
+ * Returns null if not found or expired
20
+ */
21
+ getToken(): Token | null;
22
+ /**
23
+ * Check if token exists (not expired)
24
+ */
25
+ hasToken(): boolean;
26
+ /**
27
+ * Clear token from storage
28
+ */
29
+ clearToken(): void;
30
+ /**
31
+ * Check if token is expired
32
+ */
33
+ private isExpired;
34
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TokenStorageService = void 0;
4
+ /**
5
+ * Token storage service (decorator pattern)
6
+ * Adds domain logic (expiry check, JSON serialization) on top of generic storage
7
+ */
8
+ class TokenStorageService {
9
+ storage;
10
+ tokenKey = 'socialUserToken'; // Backward compatible key
11
+ expiryKey = 'socialUserToken_expiry';
12
+ constructor(storage) {
13
+ this.storage = storage;
14
+ }
15
+ /**
16
+ * Save social authentication token
17
+ * @param token Token with expiry information (Date)
18
+ */
19
+ saveToken(token) {
20
+ try {
21
+ this.storage.set(this.tokenKey, JSON.stringify(token));
22
+ // Store expiry separately for quick validation
23
+ if (token.expiresIn) {
24
+ this.storage.set(this.expiryKey, token.expiresIn.toISOString());
25
+ }
26
+ }
27
+ catch (error) {
28
+ console.error('TokenStorageService: Error saving token', error);
29
+ }
30
+ }
31
+ /**
32
+ * Get social authentication token
33
+ * Returns null if not found or expired
34
+ */
35
+ getToken() {
36
+ try {
37
+ // Check expiry first (faster than parsing JSON)
38
+ if (this.isExpired()) {
39
+ this.clearToken();
40
+ return null;
41
+ }
42
+ const raw = this.storage.get(this.tokenKey);
43
+ if (!raw) {
44
+ return null;
45
+ }
46
+ const token = JSON.parse(raw);
47
+ // Convert ISO string back to Date
48
+ if (token.expiresIn) {
49
+ token.expiresIn = new Date(token.expiresIn);
50
+ }
51
+ return token;
52
+ }
53
+ catch (error) {
54
+ console.error('TokenStorageService: Error getting token', error);
55
+ this.clearToken();
56
+ return null;
57
+ }
58
+ }
59
+ /**
60
+ * Check if token exists (not expired)
61
+ */
62
+ hasToken() {
63
+ return !this.isExpired() && this.storage.has(this.tokenKey);
64
+ }
65
+ /**
66
+ * Clear token from storage
67
+ */
68
+ clearToken() {
69
+ this.storage.remove(this.tokenKey);
70
+ this.storage.remove(this.expiryKey);
71
+ }
72
+ /**
73
+ * Check if token is expired
74
+ */
75
+ isExpired() {
76
+ const expiryRaw = this.storage.get(this.expiryKey);
77
+ if (!expiryRaw) {
78
+ return false; // No expiry set = no token or never expires
79
+ }
80
+ try {
81
+ const expiryDate = new Date(expiryRaw);
82
+ return expiryDate <= new Date();
83
+ }
84
+ catch (error) {
85
+ console.error('TokenStorageService: Error checking expiry', error);
86
+ return true; // If can't parse, consider expired
87
+ }
88
+ }
89
+ }
90
+ exports.TokenStorageService = TokenStorageService;
@@ -0,0 +1,29 @@
1
+ import { IStorageService } from "./IStorageService";
2
+ import { SocialUser } from "../models/SocialUser";
3
+ /**
4
+ * User storage service (decorator pattern)
5
+ * Adds domain logic (JSON serialization, identity transformation) on top of generic storage
6
+ */
7
+ export declare class UserStorageService {
8
+ private storage;
9
+ private readonly userKey;
10
+ constructor(storage: IStorageService);
11
+ /**
12
+ * Save social user information
13
+ * @param user Social user data
14
+ */
15
+ saveUser<T = {}>(user: SocialUser<T>): void;
16
+ /**
17
+ * Get social user information
18
+ * Returns null if not found
19
+ */
20
+ getUser<T = {}>(): SocialUser<T> | null;
21
+ /**
22
+ * Check if user exists
23
+ */
24
+ hasUser(): boolean;
25
+ /**
26
+ * Clear user from storage
27
+ */
28
+ clearUser(): void;
29
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserStorageService = void 0;
4
+ /**
5
+ * User storage service (decorator pattern)
6
+ * Adds domain logic (JSON serialization, identity transformation) on top of generic storage
7
+ */
8
+ class UserStorageService {
9
+ storage;
10
+ userKey = 'socialUser'; // Backward compatible key
11
+ constructor(storage) {
12
+ this.storage = storage;
13
+ }
14
+ /**
15
+ * Save social user information
16
+ * @param user Social user data
17
+ */
18
+ saveUser(user) {
19
+ try {
20
+ this.storage.set(this.userKey, JSON.stringify(user));
21
+ }
22
+ catch (error) {
23
+ console.error('UserStorageService: Error saving user', error);
24
+ }
25
+ }
26
+ /**
27
+ * Get social user information
28
+ * Returns null if not found
29
+ */
30
+ getUser() {
31
+ try {
32
+ const raw = this.storage.get(this.userKey);
33
+ if (!raw) {
34
+ return null;
35
+ }
36
+ return JSON.parse(raw);
37
+ }
38
+ catch (error) {
39
+ console.error('UserStorageService: Error getting user', error);
40
+ return null;
41
+ }
42
+ }
43
+ /**
44
+ * Check if user exists
45
+ */
46
+ hasUser() {
47
+ return this.storage.has(this.userKey);
48
+ }
49
+ /**
50
+ * Clear user from storage
51
+ */
52
+ clearUser() {
53
+ this.storage.remove(this.userKey);
54
+ }
55
+ }
56
+ exports.UserStorageService = UserStorageService;