@chanomhub/sdk 1.1.1 → 1.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/README.md CHANGED
@@ -139,6 +139,157 @@ export default async function Page() {
139
139
  }
140
140
  ```
141
141
 
142
+ ### OAuth Authentication (Supabase)
143
+
144
+ The SDK supports OAuth authentication via Supabase. First, install the Supabase client:
145
+
146
+ ```bash
147
+ npm install @supabase/supabase-js
148
+ ```
149
+
150
+ Configure the SDK with your Supabase credentials:
151
+
152
+ ```typescript
153
+ import { createChanomhubClient } from '@chanomhub/sdk';
154
+
155
+ const sdk = createChanomhubClient({
156
+ supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
157
+ supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
158
+ });
159
+
160
+ // Check if OAuth is available
161
+ if (sdk.auth.isOAuthEnabled()) {
162
+ // Start Google sign-in (redirects to Google)
163
+ await sdk.auth.signInWithGoogle({
164
+ redirectTo: 'http://localhost:3000/login/callback',
165
+ });
166
+ }
167
+ ```
168
+
169
+ Handle the OAuth callback:
170
+
171
+ ```typescript
172
+ // app/login/callback/page.tsx
173
+ import { createChanomhubClient } from '@chanomhub/sdk';
174
+ import Cookies from 'js-cookie';
175
+
176
+ export default async function CallbackPage() {
177
+ const sdk = createChanomhubClient({
178
+ supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
179
+ supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
180
+ });
181
+
182
+ // Exchange Supabase token for backend JWT
183
+ const result = await sdk.auth.handleCallback();
184
+
185
+ if (result) {
186
+ // Store tokens (you manage storage)
187
+ Cookies.set('token', result.token, { secure: true, sameSite: 'strict' });
188
+ Cookies.set('refreshToken', result.refreshToken);
189
+ // Redirect to home or dashboard
190
+ }
191
+ }
192
+ ```
193
+
194
+ Available OAuth methods:
195
+
196
+ ```typescript
197
+ // Sign in with specific provider
198
+ await sdk.auth.signInWithProvider('google');
199
+ await sdk.auth.signInWithProvider('discord');
200
+ await sdk.auth.signInWithProvider('github');
201
+
202
+ // Refresh backend token
203
+ const newTokens = await sdk.auth.refreshToken(refreshToken);
204
+
205
+ // Sign out (clears Supabase session)
206
+ await sdk.auth.signOut();
207
+
208
+ // Get current Supabase session
209
+ const session = await sdk.auth.getSupabaseSession();
210
+ ```
211
+
212
+ ### OAuth for React Native (Pure RN / Without Expo)
213
+
214
+ For React Native apps, install `react-native-app-auth`:
215
+
216
+ ```bash
217
+ npm install @chanomhub/sdk react-native-app-auth
218
+ ```
219
+
220
+ Configure and use native OAuth:
221
+
222
+ ```typescript
223
+ import { createChanomhubClient } from '@chanomhub/sdk';
224
+
225
+ const sdk = createChanomhubClient();
226
+
227
+ // Google Sign-In for React Native
228
+ const result = await sdk.auth.signInWithGoogleNative({
229
+ googleClientId: 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com',
230
+ googleIosClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com', // Optional
231
+ redirectUri: 'com.yourapp://oauth',
232
+ });
233
+
234
+ if (result) {
235
+ // result contains: { user, token, refreshToken }
236
+ console.log('Logged in as:', result.user.username);
237
+ }
238
+ ```
239
+
240
+ Other providers:
241
+
242
+ ```typescript
243
+ // Discord
244
+ await sdk.auth.signInWithProviderNative('discord', {
245
+ discordClientId: 'YOUR_DISCORD_CLIENT_ID',
246
+ redirectUri: 'com.yourapp://oauth',
247
+ });
248
+
249
+ // GitHub
250
+ await sdk.auth.signInWithProviderNative('github', {
251
+ githubClientId: 'YOUR_GITHUB_CLIENT_ID',
252
+ redirectUri: 'com.yourapp://oauth',
253
+ });
254
+ ```
255
+
256
+ If you handle OAuth flow yourself:
257
+
258
+ ```typescript
259
+ import { authorize } from 'react-native-app-auth';
260
+
261
+ // Use your own OAuth config
262
+ const oauthResult = await authorize(myConfig);
263
+
264
+ // Exchange with backend
265
+ const loginResult = await sdk.auth.exchangeOAuthToken(oauthResult);
266
+ ```
267
+
268
+ ### Electron / Server-side OAuth
269
+
270
+ For environments where you need to handle the OAuth redirect manually (e.g., Electron, CLI):
271
+
272
+ ```typescript
273
+ // 1. Get the OAuth URL
274
+ const options = {
275
+ skipBrowserRedirect: true,
276
+ redirectTo: 'myapp://oauth-callback',
277
+ scopes: 'email profile', // Optional
278
+ };
279
+
280
+ const { url } = await sdk.auth.signInWithGoogle(options);
281
+ // OR generic provider:
282
+ // const { url } = await sdk.auth.signInWithProvider('github', options);
283
+
284
+ if (url) {
285
+ // 2. Open URL in external browser/window (Electron example)
286
+ // shell.openExternal(url);
287
+ }
288
+
289
+ // 3. In your app's deep link handler, process the returned code/token
290
+ // This depends on how you handle deep links in Electron
291
+ ```
292
+
142
293
  ---
143
294
 
144
295
  ## 📁 Project Structure
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Auth Repository Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=auth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.test.d.ts","sourceRoot":"","sources":["../../__tests__/auth.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Auth Repository Tests
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const authRepository_1 = require("../repositories/authRepository");
8
+ (0, vitest_1.describe)('authRepository', () => {
9
+ let mockFetcher;
10
+ let config;
11
+ (0, vitest_1.beforeEach)(() => {
12
+ mockFetcher = vitest_1.vi.fn();
13
+ config = {
14
+ apiUrl: 'https://api.chanomhub.com',
15
+ cdnUrl: 'https://cdn.chanomhub.com',
16
+ };
17
+ });
18
+ (0, vitest_1.describe)('isOAuthEnabled', () => {
19
+ (0, vitest_1.it)('should return false when Supabase is not configured', () => {
20
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
21
+ (0, vitest_1.expect)(auth.isOAuthEnabled()).toBe(false);
22
+ });
23
+ (0, vitest_1.it)('should return true when Supabase URL and key are provided', () => {
24
+ config.supabaseUrl = 'https://test.supabase.co';
25
+ config.supabaseAnonKey = 'test-anon-key';
26
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
27
+ (0, vitest_1.expect)(auth.isOAuthEnabled()).toBe(true);
28
+ });
29
+ (0, vitest_1.it)('should return false when only URL is provided', () => {
30
+ config.supabaseUrl = 'https://test.supabase.co';
31
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
32
+ (0, vitest_1.expect)(auth.isOAuthEnabled()).toBe(false);
33
+ });
34
+ });
35
+ (0, vitest_1.describe)('signInWithProvider', () => {
36
+ (0, vitest_1.it)('should throw error when Supabase is not configured', async () => {
37
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
38
+ await (0, vitest_1.expect)(auth.signInWithProvider('google')).rejects.toThrow('Supabase is not configured');
39
+ });
40
+ });
41
+ (0, vitest_1.describe)('signInWithGoogle', () => {
42
+ (0, vitest_1.it)('should throw error when Supabase is not configured', async () => {
43
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
44
+ await (0, vitest_1.expect)(auth.signInWithGoogle()).rejects.toThrow('Supabase is not configured');
45
+ });
46
+ });
47
+ (0, vitest_1.describe)('refreshToken', () => {
48
+ (0, vitest_1.it)('should call refresh token endpoint with correct body', async () => {
49
+ mockFetcher.mockResolvedValue({
50
+ data: { token: 'new-token', refreshToken: 'new-refresh-token' },
51
+ error: undefined,
52
+ });
53
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
54
+ const result = await auth.refreshToken('old-refresh-token');
55
+ (0, vitest_1.expect)(mockFetcher).toHaveBeenCalledWith('/api/users/refresh-token', {
56
+ method: 'POST',
57
+ body: { refreshToken: 'old-refresh-token' },
58
+ });
59
+ (0, vitest_1.expect)(result).toEqual({ token: 'new-token', refreshToken: 'new-refresh-token' });
60
+ });
61
+ (0, vitest_1.it)('should return null when refresh fails', async () => {
62
+ mockFetcher.mockResolvedValue({
63
+ data: null,
64
+ error: 'Token expired',
65
+ });
66
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
67
+ const result = await auth.refreshToken('expired-token');
68
+ (0, vitest_1.expect)(result).toBeNull();
69
+ });
70
+ });
71
+ (0, vitest_1.describe)('getSupabaseSession', () => {
72
+ (0, vitest_1.it)('should return null when Supabase is not configured', async () => {
73
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
74
+ const session = await auth.getSupabaseSession();
75
+ (0, vitest_1.expect)(session).toBeNull();
76
+ });
77
+ });
78
+ // ============================================
79
+ // React Native OAuth Tests
80
+ // ============================================
81
+ (0, vitest_1.describe)('signInWithGoogleNative', () => {
82
+ (0, vitest_1.it)('should throw error when googleClientId is not provided', async () => {
83
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
84
+ await (0, vitest_1.expect)(auth.signInWithGoogleNative({ redirectUri: 'com.app://oauth' })).rejects.toThrow('Missing client ID for google');
85
+ });
86
+ (0, vitest_1.it)('should throw error when redirectUri is not provided', async () => {
87
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
88
+ await (0, vitest_1.expect)(auth.signInWithGoogleNative({
89
+ googleClientId: 'test-client-id',
90
+ redirectUri: '',
91
+ })).rejects.toThrow('Missing redirectUri');
92
+ });
93
+ });
94
+ (0, vitest_1.describe)('signInWithProviderNative', () => {
95
+ (0, vitest_1.it)('should throw error when discordClientId is missing for discord', async () => {
96
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
97
+ await (0, vitest_1.expect)(auth.signInWithProviderNative('discord', { redirectUri: 'com.app://oauth' })).rejects.toThrow('Missing client ID for discord');
98
+ });
99
+ (0, vitest_1.it)('should throw error when githubClientId is missing for github', async () => {
100
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
101
+ await (0, vitest_1.expect)(auth.signInWithProviderNative('github', { redirectUri: 'com.app://oauth' })).rejects.toThrow('Missing client ID for github');
102
+ });
103
+ });
104
+ (0, vitest_1.describe)('exchangeOAuthToken', () => {
105
+ (0, vitest_1.it)('should exchange OAuth token with backend', async () => {
106
+ mockFetcher.mockResolvedValue({
107
+ data: {
108
+ user: { id: 1, username: 'test' },
109
+ token: 'backend-token',
110
+ refreshToken: 'backend-refresh',
111
+ },
112
+ error: undefined,
113
+ });
114
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
115
+ const result = await auth.exchangeOAuthToken({
116
+ accessToken: 'oauth-access-token',
117
+ idToken: 'google-id-token',
118
+ });
119
+ (0, vitest_1.expect)(mockFetcher).toHaveBeenCalledWith('/api/users/login-oauth', {
120
+ method: 'POST',
121
+ body: {
122
+ accessToken: 'google-id-token', // Uses idToken when available
123
+ provider: 'google',
124
+ },
125
+ });
126
+ (0, vitest_1.expect)(result).toEqual({
127
+ user: { id: 1, username: 'test' },
128
+ token: 'backend-token',
129
+ refreshToken: 'backend-refresh',
130
+ });
131
+ });
132
+ (0, vitest_1.it)('should use accessToken when idToken is not available', async () => {
133
+ mockFetcher.mockResolvedValue({
134
+ data: { user: { id: 1 }, token: 'token', refreshToken: 'refresh' },
135
+ error: undefined,
136
+ });
137
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
138
+ await auth.exchangeOAuthToken({ accessToken: 'discord-token' });
139
+ (0, vitest_1.expect)(mockFetcher).toHaveBeenCalledWith('/api/users/login-oauth', {
140
+ method: 'POST',
141
+ body: {
142
+ accessToken: 'discord-token',
143
+ provider: 'oauth',
144
+ },
145
+ });
146
+ });
147
+ (0, vitest_1.it)('should return null when no token available', async () => {
148
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
149
+ const result = await auth.exchangeOAuthToken({ accessToken: '' });
150
+ (0, vitest_1.expect)(result).toBeNull();
151
+ });
152
+ });
153
+ // ============================================
154
+ // Electron / Server-side OAuth Tests
155
+ // ============================================
156
+ (0, vitest_1.describe)('getOAuthUrl', () => {
157
+ (0, vitest_1.it)('should return OAuth URL when Supabase is configured', async () => {
158
+ config.supabaseUrl = 'https://test.supabase.co';
159
+ config.supabaseAnonKey = 'test-key';
160
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
161
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
162
+ // Mock Supabase client setup would go here
163
+ });
164
+ });
165
+ (0, vitest_1.it)('should have getOAuthUrl method', () => {
166
+ const auth = (0, authRepository_1.createAuthRepository)(mockFetcher, config);
167
+ (0, vitest_1.expect)(typeof auth.getOAuthUrl).toBe('function');
168
+ });
169
+ });
170
+ //# sourceMappingURL=auth.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../__tests__/auth.test.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -10,6 +10,10 @@ export interface ChanomhubConfig {
10
10
  token?: string;
11
11
  /** Default cache duration in seconds (0 = no cache) */
12
12
  defaultCacheSeconds?: number;
13
+ /** Supabase project URL (required for OAuth) */
14
+ supabaseUrl?: string;
15
+ /** Supabase anon key (required for OAuth) */
16
+ supabaseAnonKey?: string;
13
17
  }
14
18
  export declare const DEFAULT_CONFIG: ChanomhubConfig;
15
19
  /** Article status enum */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC5B,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,EAAE,eAI5B,CAAC;AAEF,0BAA0B;AAC1B,MAAM,MAAM,aAAa,GACnB,OAAO,GACP,gBAAgB,GAChB,WAAW,GACX,UAAU,GACV,cAAc,GACd,gBAAgB,CAAC;AAEvB,uBAAuB;AACvB,MAAM,MAAM,UAAU,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,GACP,eAAe,GACf,SAAS,GACT,UAAU,GACV,OAAO,GACP,aAAa,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC5B,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,eAI5B,CAAC;AAEF,0BAA0B;AAC1B,MAAM,MAAM,aAAa,GACnB,OAAO,GACP,gBAAgB,GAChB,WAAW,GACX,UAAU,GACV,cAAc,GACd,gBAAgB,CAAC;AAEvB,uBAAuB;AACvB,MAAM,MAAM,UAAU,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,GACP,eAAe,GACf,SAAS,GACT,UAAU,GACV,OAAO,GACP,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAaU,QAAA,cAAc,GAAoB;IAC3C,MAAM,EAAE,2BAA2B;IACnC,MAAM,EAAE,qDAAqD;IAC7D,mBAAmB,EAAE,IAAI;CAC5B,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAiBU,QAAA,cAAc,GAAoB;IAC3C,MAAM,EAAE,2BAA2B;IACnC,MAAM,EAAE,qDAAqD;IAC7D,mBAAmB,EAAE,IAAI;CAC5B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@
31
31
  * ```
32
32
  */
33
33
  import { type GraphQLFetcher } from './client';
34
- import { type ArticleRepository, type FavoritesRepository, type UsersRepository, type SearchRepository } from './repositories';
34
+ import { type ArticleRepository, type FavoritesRepository, type UsersRepository, type SearchRepository, type AuthRepository } from './repositories';
35
35
  import { type ChanomhubConfig } from './config';
36
36
  export * from './types';
37
37
  export * from './config';
@@ -47,6 +47,8 @@ export interface ChanomhubClient {
47
47
  users: UsersRepository;
48
48
  /** Search operations */
49
49
  search: SearchRepository;
50
+ /** Authentication operations (requires Supabase config for OAuth) */
51
+ auth: AuthRepository;
50
52
  /** Raw GraphQL fetcher for custom queries */
51
53
  graphql: GraphQLFetcher;
52
54
  /** SDK configuration */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAKH,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhE,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC5B,yBAAyB;IACzB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,2BAA2B;IAC3B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,8BAA8B;IAC9B,KAAK,EAAE,eAAe,CAAC;IACvB,wBAAwB;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,6CAA6C;IAC7C,OAAO,EAAE,cAAc,CAAC;IACxB,wBAAwB;IACxB,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAqB5F;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACtC,eAAe,CAMjB;AAGD,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACtF,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhE,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC5B,yBAAyB;IACzB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,2BAA2B;IAC3B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,8BAA8B;IAC9B,KAAK,EAAE,eAAe,CAAC;IACvB,wBAAwB;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,qEAAqE;IACrE,IAAI,EAAE,cAAc,CAAC;IACrB,6CAA6C;IAC7C,OAAO,EAAE,cAAc,CAAC;IACxB,wBAAwB;IACxB,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAuB5F;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACtC,eAAe,CAMjB;AAGD,eAAe,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -91,11 +91,13 @@ function createChanomhubClient(config = {}) {
91
91
  const favorites = (0, repositories_1.createFavoritesRepository)(rest);
92
92
  const users = (0, repositories_1.createUsersRepository)(rest);
93
93
  const search = (0, repositories_1.createSearchRepository)(graphql);
94
+ const auth = (0, repositories_1.createAuthRepository)(rest, fullConfig);
94
95
  return {
95
96
  articles,
96
97
  favorites,
97
98
  users,
98
99
  search,
100
+ auth,
99
101
  graphql,
100
102
  config: fullConfig,
101
103
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;;;;;;;;;;;;;;;AA2DH,sDAqBC;AAUD,8DASC;AAjGD,qCAAsF;AACtF,iDASwB;AACxB,qCAAgE;AAEhE,kBAAkB;AAClB,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB;AACzB,kDAAwD;AAA/C,2GAAA,eAAe,OAAA;AAkBxB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,qBAAqB,CAAC,SAAmC,EAAE;IACvE,MAAM,UAAU,GAAoB;QAChC,GAAG,uBAAc;QACjB,GAAG,MAAM;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,IAAA,4BAAmB,EAAC,UAAU,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAA,yBAAgB,EAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAA,sCAAuB,EAAC,OAAO,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAA,wCAAyB,EAAC,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,IAAA,oCAAqB,EAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAA,qCAAsB,EAAC,OAAO,CAAC,CAAC;IAE/C,OAAO;QACH,QAAQ;QACR,SAAS;QACT,KAAK;QACL,MAAM;QACN,OAAO;QACP,MAAM,EAAE,UAAU;KACrB,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CACrC,KAAa,EACb,SAAmC,EAAE;IAErC,OAAO,qBAAqB,CAAC;QACzB,GAAG,MAAM;QACT,KAAK;QACL,mBAAmB,EAAE,CAAC,EAAE,2CAA2C;KACtE,CAAC,CAAC;AACP,CAAC;AAED,iBAAiB;AACjB,kBAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;;;;;;;;;;;;;;;AA+DH,sDAuBC;AAUD,8DASC;AAvGD,qCAAsF;AACtF,iDAWwB;AACxB,qCAAgE;AAEhE,kBAAkB;AAClB,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB;AACzB,kDAAwD;AAA/C,2GAAA,eAAe,OAAA;AAoBxB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,qBAAqB,CAAC,SAAmC,EAAE;IACvE,MAAM,UAAU,GAAoB;QAChC,GAAG,uBAAc;QACjB,GAAG,MAAM;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,IAAA,4BAAmB,EAAC,UAAU,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAA,yBAAgB,EAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAA,sCAAuB,EAAC,OAAO,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAA,wCAAyB,EAAC,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,IAAA,oCAAqB,EAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAA,qCAAsB,EAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAA,mCAAoB,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEpD,OAAO;QACH,QAAQ;QACR,SAAS;QACT,KAAK;QACL,MAAM;QACN,IAAI;QACJ,OAAO;QACP,MAAM,EAAE,UAAU;KACrB,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CACrC,KAAa,EACb,SAAmC,EAAE;IAErC,OAAO,qBAAqB,CAAC;QACzB,GAAG,MAAM;QACT,KAAK;QACL,mBAAmB,EAAE,CAAC,EAAE,2CAA2C;KACtE,CAAC,CAAC;AACP,CAAC;AAED,iBAAiB;AACjB,kBAAe,qBAAqB,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Chanomhub SDK - Auth Repository
3
+ *
4
+ * Handles OAuth authentication via Supabase and token exchange with backend.
5
+ */
6
+ import type { ChanomhubConfig } from '../config';
7
+ import type { RestFetcher } from '../client';
8
+ import type { OAuthProvider, OAuthOptions, LoginResponse, RefreshResponse, SupabaseSession, NativeOAuthConfig, NativeOAuthOptions, NativeOAuthResult } from '../types/auth';
9
+ export interface AuthRepository {
10
+ /** Check if Supabase OAuth is configured and available */
11
+ isOAuthEnabled(): boolean;
12
+ /** Sign in with Google OAuth - redirects to Google login page (Web only) */
13
+ signInWithGoogle(options?: OAuthOptions): Promise<{
14
+ url: string | null;
15
+ }>;
16
+ /** Sign in with any supported OAuth provider */
17
+ signInWithProvider(provider: OAuthProvider, options?: OAuthOptions): Promise<{
18
+ url: string | null;
19
+ }>;
20
+ /**
21
+ * Get the OAuth URL for manual redirect handling (Electron, etc.)
22
+ * @param provider - OAuth provider
23
+ * @param options - OAuth options
24
+ * @returns OAuth URL string
25
+ */
26
+ getOAuthUrl(provider: OAuthProvider, options?: OAuthOptions): Promise<string | null>;
27
+ /**
28
+ * Sign in with Google OAuth for React Native apps.
29
+ * Uses react-native-app-auth under the hood.
30
+ * @param nativeConfig - Native OAuth configuration with client IDs and redirect URI
31
+ * @param options - Additional options like scopes
32
+ * @returns Login response with user and tokens from backend
33
+ */
34
+ signInWithGoogleNative(nativeConfig: NativeOAuthConfig, options?: NativeOAuthOptions): Promise<LoginResponse | null>;
35
+ /**
36
+ * Sign in with any OAuth provider for React Native apps.
37
+ * Uses react-native-app-auth under the hood.
38
+ * @param provider - OAuth provider (google, discord, github)
39
+ * @param nativeConfig - Native OAuth configuration
40
+ * @param options - Additional options
41
+ * @returns Login response with user and tokens from backend
42
+ */
43
+ signInWithProviderNative(provider: OAuthProvider, nativeConfig: NativeOAuthConfig, options?: NativeOAuthOptions): Promise<LoginResponse | null>;
44
+ /**
45
+ * Exchange OAuth token from react-native-app-auth with backend.
46
+ * Use this if you handle the OAuth flow yourself.
47
+ * @param oauthResult - Result from react-native-app-auth authorize()
48
+ * @returns Login response with user and backend tokens
49
+ */
50
+ exchangeOAuthToken(oauthResult: NativeOAuthResult): Promise<LoginResponse | null>;
51
+ /**
52
+ * Handle OAuth callback after redirect back from provider.
53
+ * Exchanges Supabase access token for backend JWT.
54
+ * Call this on your OAuth callback page (Web only).
55
+ */
56
+ handleCallback(): Promise<LoginResponse | null>;
57
+ /** Sign out from Supabase (clears Supabase session only) */
58
+ signOut(): Promise<void>;
59
+ /** Refresh the backend access token using refresh token */
60
+ refreshToken(refreshToken: string): Promise<RefreshResponse | null>;
61
+ /** Get current Supabase session (if any) */
62
+ getSupabaseSession(): Promise<SupabaseSession | null>;
63
+ }
64
+ /**
65
+ * Creates an auth repository for OAuth operations
66
+ *
67
+ * @param fetcher - REST API fetcher
68
+ * @param config - SDK configuration with optional Supabase settings
69
+ */
70
+ export declare function createAuthRepository(fetcher: RestFetcher, config: ChanomhubConfig): AuthRepository;
71
+ //# sourceMappingURL=authRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authRepository.d.ts","sourceRoot":"","sources":["../../repositories/authRepository.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,eAAe,CAAC;AAsBvB,MAAM,WAAW,cAAc;IAC3B,0DAA0D;IAC1D,cAAc,IAAI,OAAO,CAAC;IAE1B,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE1E,gDAAgD;IAChD,kBAAkB,CACd,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,YAAY,GACvB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAErF;;;;;;OAMG;IACH,sBAAsB,CAClB,YAAY,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC7B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEjC;;;;;;;OAOG;IACH,wBAAwB,CACpB,QAAQ,EAAE,aAAa,EACvB,YAAY,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE,kBAAkB,GAC7B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAElF;;;;OAIG;IACH,cAAc,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEhD,4DAA4D;IAC5D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB,2DAA2D;IAC3D,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEpE,4CAA4C;IAC5C,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;CACzD;AAuBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,cAAc,CAwUlG"}
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ /**
3
+ * Chanomhub SDK - Auth Repository
4
+ *
5
+ * Handles OAuth authentication via Supabase and token exchange with backend.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.createAuthRepository = createAuthRepository;
42
+ /**
43
+ * Try to dynamically import @supabase/supabase-js
44
+ * Returns null if not installed
45
+ */
46
+ async function tryGetSupabaseClient(config) {
47
+ if (!config.supabaseUrl || !config.supabaseAnonKey) {
48
+ return null;
49
+ }
50
+ try {
51
+ // Dynamic import to handle optional dependency
52
+ const { createClient } = await Promise.resolve().then(() => __importStar(require('@supabase/supabase-js')));
53
+ return createClient(config.supabaseUrl, config.supabaseAnonKey);
54
+ }
55
+ catch (_a) {
56
+ console.warn('Supabase client not available. Install @supabase/supabase-js to enable OAuth.');
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Creates an auth repository for OAuth operations
62
+ *
63
+ * @param fetcher - REST API fetcher
64
+ * @param config - SDK configuration with optional Supabase settings
65
+ */
66
+ function createAuthRepository(fetcher, config) {
67
+ // Cache the Supabase client promise
68
+ let supabaseClientPromise = null;
69
+ async function getSupabaseClient() {
70
+ if (!supabaseClientPromise) {
71
+ supabaseClientPromise = tryGetSupabaseClient(config);
72
+ }
73
+ return supabaseClientPromise;
74
+ }
75
+ function isOAuthEnabled() {
76
+ return Boolean(config.supabaseUrl && config.supabaseAnonKey);
77
+ }
78
+ async function getOAuthUrl(provider, options = {}) {
79
+ const client = await getSupabaseClient();
80
+ if (!client) {
81
+ throw new Error('Supabase is not configured. Please provide supabaseUrl and supabaseAnonKey in config.');
82
+ }
83
+ const { data, error } = await client.auth.signInWithOAuth({
84
+ provider,
85
+ options: {
86
+ redirectTo: options.redirectTo,
87
+ scopes: options.scopes,
88
+ queryParams: options.queryParams,
89
+ skipBrowserRedirect: true,
90
+ },
91
+ });
92
+ if (error) {
93
+ console.error(`Get OAuth URL error (${provider}):`, error.message);
94
+ throw error;
95
+ }
96
+ return data.url || null;
97
+ }
98
+ async function signInWithProvider(provider, options = {}) {
99
+ const client = await getSupabaseClient();
100
+ if (!client) {
101
+ throw new Error('Supabase is not configured. Please provide supabaseUrl and supabaseAnonKey in config, ' +
102
+ 'and install @supabase/supabase-js package.');
103
+ }
104
+ const { data, error } = await client.auth.signInWithOAuth({
105
+ provider,
106
+ options: {
107
+ redirectTo: options.redirectTo,
108
+ scopes: options.scopes,
109
+ queryParams: options.queryParams,
110
+ skipBrowserRedirect: options.skipBrowserRedirect,
111
+ },
112
+ });
113
+ if (error) {
114
+ console.error(`OAuth sign-in error (${provider}):`, error.message);
115
+ throw error;
116
+ }
117
+ // If skipBrowserRedirect is true, return the URL
118
+ if (options.skipBrowserRedirect && data.url) {
119
+ return { url: data.url };
120
+ }
121
+ return { url: null };
122
+ }
123
+ async function signInWithGoogle(options = {}) {
124
+ return signInWithProvider('google', options);
125
+ }
126
+ async function handleCallback() {
127
+ const client = await getSupabaseClient();
128
+ if (!client) {
129
+ throw new Error('Supabase is not configured for OAuth callback handling.');
130
+ }
131
+ // Get the session that Supabase created from the OAuth callback
132
+ const { data, error } = await client.auth.getSession();
133
+ if (error) {
134
+ console.error('Failed to get Supabase session:', error.message);
135
+ return null;
136
+ }
137
+ if (!data.session) {
138
+ console.error('No Supabase session found. User may not have completed OAuth flow.');
139
+ return null;
140
+ }
141
+ // Exchange Supabase token for backend JWT
142
+ const { data: loginData, error: loginError } = await fetcher('/api/users/login-supabase', {
143
+ method: 'POST',
144
+ body: {
145
+ accessToken: data.session.access_token,
146
+ },
147
+ });
148
+ if (loginError) {
149
+ console.error('Failed to exchange token with backend:', loginError);
150
+ return null;
151
+ }
152
+ return loginData;
153
+ }
154
+ async function signOut() {
155
+ const client = await getSupabaseClient();
156
+ if (client) {
157
+ const { error } = await client.auth.signOut();
158
+ if (error) {
159
+ console.error('Supabase sign-out error:', error.message);
160
+ }
161
+ }
162
+ // Note: This only clears Supabase session.
163
+ // The frontend is responsible for clearing backend tokens from cookies/storage.
164
+ }
165
+ async function refreshToken(refreshToken) {
166
+ const { data, error } = await fetcher('/api/users/refresh-token', {
167
+ method: 'POST',
168
+ body: { refreshToken },
169
+ });
170
+ if (error) {
171
+ console.error('Failed to refresh token:', error);
172
+ return null;
173
+ }
174
+ return data;
175
+ }
176
+ async function getSupabaseSession() {
177
+ const client = await getSupabaseClient();
178
+ if (!client) {
179
+ return null;
180
+ }
181
+ const { data, error } = await client.auth.getSession();
182
+ if (error) {
183
+ console.error('Failed to get Supabase session:', error.message);
184
+ return null;
185
+ }
186
+ return data.session;
187
+ }
188
+ // ============================================
189
+ // React Native OAuth Methods
190
+ // ============================================
191
+ /** OAuth provider configurations */
192
+ const OAUTH_CONFIGS = {
193
+ google: {
194
+ issuer: 'https://accounts.google.com',
195
+ defaultScopes: ['openid', 'email', 'profile'],
196
+ },
197
+ discord: {
198
+ serviceConfiguration: {
199
+ authorizationEndpoint: 'https://discord.com/api/oauth2/authorize',
200
+ tokenEndpoint: 'https://discord.com/api/oauth2/token',
201
+ },
202
+ issuer: '',
203
+ defaultScopes: ['identify', 'email'],
204
+ },
205
+ github: {
206
+ serviceConfiguration: {
207
+ authorizationEndpoint: 'https://github.com/login/oauth/authorize',
208
+ tokenEndpoint: 'https://github.com/login/oauth/access_token',
209
+ },
210
+ issuer: '',
211
+ defaultScopes: ['read:user', 'user:email'],
212
+ },
213
+ facebook: {
214
+ serviceConfiguration: {
215
+ authorizationEndpoint: 'https://www.facebook.com/v18.0/dialog/oauth',
216
+ tokenEndpoint: 'https://graph.facebook.com/v18.0/oauth/access_token',
217
+ },
218
+ issuer: '',
219
+ defaultScopes: ['email', 'public_profile'],
220
+ },
221
+ };
222
+ function getClientIdForProvider(provider, nativeConfig) {
223
+ switch (provider) {
224
+ case 'google':
225
+ return nativeConfig.googleClientId || '';
226
+ case 'discord':
227
+ return nativeConfig.discordClientId || '';
228
+ case 'github':
229
+ return nativeConfig.githubClientId || '';
230
+ default:
231
+ return '';
232
+ }
233
+ }
234
+ async function signInWithProviderNative(provider, nativeConfig, options = {}) {
235
+ const clientId = getClientIdForProvider(provider, nativeConfig);
236
+ if (!clientId) {
237
+ throw new Error(`Missing client ID for ${provider}. Please provide ${provider}ClientId in nativeConfig.`);
238
+ }
239
+ if (!nativeConfig.redirectUri) {
240
+ throw new Error('Missing redirectUri in nativeConfig.');
241
+ }
242
+ // Try to dynamically import react-native-app-auth
243
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
+ let authorize;
245
+ try {
246
+ const appAuth = await Promise.resolve().then(() => __importStar(require('react-native-app-auth')));
247
+ authorize = appAuth.authorize;
248
+ }
249
+ catch (_a) {
250
+ throw new Error('react-native-app-auth is not installed. Please install it: npm install react-native-app-auth');
251
+ }
252
+ const providerConfig = OAUTH_CONFIGS[provider];
253
+ const scopes = options.scopes || providerConfig.defaultScopes;
254
+ const authConfig = {
255
+ clientId,
256
+ redirectUrl: nativeConfig.redirectUri,
257
+ scopes,
258
+ usePKCE: options.usePKCE !== false, // Default to true
259
+ };
260
+ // Use issuer or serviceConfiguration
261
+ if (providerConfig.issuer) {
262
+ authConfig.issuer = providerConfig.issuer;
263
+ }
264
+ else if (providerConfig.serviceConfiguration) {
265
+ authConfig.serviceConfiguration = providerConfig.serviceConfiguration;
266
+ }
267
+ // For Google iOS, use clientId specific config
268
+ if (provider === 'google' && nativeConfig.googleIosClientId) {
269
+ // iOS uses different clientId format
270
+ authConfig.clientId = nativeConfig.googleIosClientId;
271
+ }
272
+ try {
273
+ const result = await authorize(authConfig);
274
+ return exchangeOAuthToken(result);
275
+ }
276
+ catch (error) {
277
+ console.error(`Native OAuth error (${provider}):`, error);
278
+ throw error;
279
+ }
280
+ }
281
+ async function signInWithGoogleNative(nativeConfig, options = {}) {
282
+ return signInWithProviderNative('google', nativeConfig, options);
283
+ }
284
+ async function exchangeOAuthToken(oauthResult) {
285
+ // Use idToken for Google (OpenID Connect) or accessToken for others
286
+ const tokenToExchange = oauthResult.idToken || oauthResult.accessToken;
287
+ if (!tokenToExchange) {
288
+ console.error('No token available to exchange with backend');
289
+ return null;
290
+ }
291
+ // Exchange OAuth token for backend JWT
292
+ const { data, error } = await fetcher('/api/users/login-oauth', {
293
+ method: 'POST',
294
+ body: {
295
+ accessToken: tokenToExchange,
296
+ provider: oauthResult.idToken ? 'google' : 'oauth', // Backend needs to know provider
297
+ },
298
+ });
299
+ if (error) {
300
+ console.error('Failed to exchange OAuth token with backend:', error);
301
+ return null;
302
+ }
303
+ return data;
304
+ }
305
+ return {
306
+ isOAuthEnabled,
307
+ signInWithGoogle,
308
+ signInWithProvider,
309
+ getOAuthUrl,
310
+ signInWithGoogleNative,
311
+ signInWithProviderNative,
312
+ exchangeOAuthToken,
313
+ handleCallback,
314
+ signOut,
315
+ refreshToken,
316
+ getSupabaseSession,
317
+ };
318
+ }
319
+ //# sourceMappingURL=authRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authRepository.js","sourceRoot":"","sources":["../../repositories/authRepository.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,5 @@ export { createArticleRepository, type ArticleRepository } from './articleReposi
5
5
  export { createFavoritesRepository, type FavoritesRepository, type FavoriteResponse, } from './favoritesRepository';
6
6
  export { createUsersRepository, type UsersRepository } from './usersRepository';
7
7
  export { createSearchRepository, type SearchRepository, type SearchOptions, } from './searchRepository';
8
+ export { createAuthRepository, type AuthRepository } from './authRepository';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../repositories/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EACH,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACH,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACrB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../repositories/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EACH,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACH,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -3,7 +3,7 @@
3
3
  * Chanomhub SDK - Repositories Index
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createSearchRepository = exports.createUsersRepository = exports.createFavoritesRepository = exports.createArticleRepository = void 0;
6
+ exports.createAuthRepository = exports.createSearchRepository = exports.createUsersRepository = exports.createFavoritesRepository = exports.createArticleRepository = void 0;
7
7
  var articleRepository_1 = require("./articleRepository");
8
8
  Object.defineProperty(exports, "createArticleRepository", { enumerable: true, get: function () { return articleRepository_1.createArticleRepository; } });
9
9
  var favoritesRepository_1 = require("./favoritesRepository");
@@ -12,4 +12,6 @@ var usersRepository_1 = require("./usersRepository");
12
12
  Object.defineProperty(exports, "createUsersRepository", { enumerable: true, get: function () { return usersRepository_1.createUsersRepository; } });
13
13
  var searchRepository_1 = require("./searchRepository");
14
14
  Object.defineProperty(exports, "createSearchRepository", { enumerable: true, get: function () { return searchRepository_1.createSearchRepository; } });
15
+ var authRepository_1 = require("./authRepository");
16
+ Object.defineProperty(exports, "createAuthRepository", { enumerable: true, get: function () { return authRepository_1.createAuthRepository; } });
15
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../repositories/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,yDAAsF;AAA7E,4HAAA,uBAAuB,OAAA;AAChC,6DAI+B;AAH3B,gIAAA,yBAAyB,OAAA;AAI7B,qDAAgF;AAAvE,wHAAA,qBAAqB,OAAA;AAC9B,uDAI4B;AAHxB,0HAAA,sBAAsB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../repositories/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,yDAAsF;AAA7E,4HAAA,uBAAuB,OAAA;AAChC,6DAI+B;AAH3B,gIAAA,yBAAyB,OAAA;AAI7B,qDAAgF;AAAvE,wHAAA,qBAAqB,OAAA;AAC9B,uDAI4B;AAHxB,0HAAA,sBAAsB,OAAA;AAI1B,mDAA6E;AAApE,sHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Chanomhub SDK - Auth Types
3
+ */
4
+ import type { User } from './user';
5
+ /** Supported OAuth providers */
6
+ export type OAuthProvider = 'google' | 'discord' | 'github' | 'facebook';
7
+ /** OAuth redirect options */
8
+ export interface OAuthOptions {
9
+ /** URL to redirect to after OAuth */
10
+ redirectTo?: string;
11
+ /** Additional scopes to request */
12
+ scopes?: string;
13
+ /** Skip automatic browser redirect (useful for Electron/Server-side) */
14
+ skipBrowserRedirect?: boolean;
15
+ /** Additional query parameters for the OAuth URL */
16
+ queryParams?: {
17
+ [key: string]: string;
18
+ };
19
+ }
20
+ /** Login response from backend after token exchange */
21
+ export interface LoginResponse {
22
+ user: User;
23
+ token: string;
24
+ refreshToken: string;
25
+ }
26
+ /** Token refresh response from backend */
27
+ export interface RefreshResponse {
28
+ token: string;
29
+ refreshToken?: string;
30
+ }
31
+ /** Auth session state */
32
+ export interface AuthSession {
33
+ user: User;
34
+ token: string;
35
+ refreshToken: string;
36
+ expiresAt?: number;
37
+ }
38
+ /** Supabase session (minimal type for SDK use) */
39
+ export interface SupabaseSession {
40
+ access_token: string;
41
+ refresh_token: string;
42
+ expires_at?: number;
43
+ user: {
44
+ id: string;
45
+ email?: string;
46
+ };
47
+ }
48
+ /** Backend login request */
49
+ export interface LoginSupabaseRequest {
50
+ accessToken: string;
51
+ }
52
+ /** Backend refresh token request */
53
+ export interface RefreshTokenRequest {
54
+ refreshToken: string;
55
+ }
56
+ /** Native OAuth provider configuration for React Native */
57
+ export interface NativeOAuthConfig {
58
+ /** Google OAuth client ID (for Android/iOS) */
59
+ googleClientId?: string;
60
+ /** Google iOS client ID (optional, for iOS-specific config) */
61
+ googleIosClientId?: string;
62
+ /** Discord OAuth client ID */
63
+ discordClientId?: string;
64
+ /** GitHub OAuth client ID */
65
+ githubClientId?: string;
66
+ /** Custom redirect URI (e.g., com.yourapp://oauth) */
67
+ redirectUri: string;
68
+ /** Additional scopes to request */
69
+ scopes?: string[];
70
+ }
71
+ /** Native OAuth authorization result from react-native-app-auth */
72
+ export interface NativeOAuthResult {
73
+ /** Access token from OAuth provider */
74
+ accessToken: string;
75
+ /** ID token (for OpenID Connect providers like Google) */
76
+ idToken?: string;
77
+ /** Refresh token */
78
+ refreshToken?: string;
79
+ /** Token expiration date */
80
+ accessTokenExpirationDate?: string;
81
+ /** Token type (usually 'Bearer') */
82
+ tokenType?: string;
83
+ /** Scopes granted */
84
+ scopes?: string[];
85
+ }
86
+ /** Options for native OAuth sign-in */
87
+ export interface NativeOAuthOptions {
88
+ /** Additional scopes to request */
89
+ scopes?: string[];
90
+ /** Use PKCE (recommended, default: true) */
91
+ usePKCE?: boolean;
92
+ }
93
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../types/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,gCAAgC;AAChC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEzE,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IACzB,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oDAAoD;IACpD,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC3C;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,yBAAyB;AACzB,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE;QACF,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACL;AAED,4BAA4B;AAC5B,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,oCAAoC;AACpC,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,MAAM,CAAC;CACxB;AAMD,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAC9B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8BAA8B;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAC9B,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IAC/B,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Chanomhub SDK - Auth Types
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../types/auth.ts"],"names":[],"mappings":";AAAA;;GAEG"}
@@ -4,4 +4,5 @@
4
4
  export * from './common';
5
5
  export * from './article';
6
6
  export * from './user';
7
+ export * from './auth';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC"}
@@ -20,4 +20,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  __exportStar(require("./common"), exports);
21
21
  __exportStar(require("./article"), exports);
22
22
  __exportStar(require("./user"), exports);
23
+ __exportStar(require("./auth"), exports);
23
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../types/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,2CAAyB;AACzB,4CAA0B;AAC1B,yCAAuB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../types/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,2CAAyB;AACzB,4CAA0B;AAC1B,yCAAuB;AACvB,yCAAuB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chanomhub/sdk",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "ChanomHub SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -42,6 +42,7 @@
42
42
  "author": "",
43
43
  "license": "ISC",
44
44
  "devDependencies": {
45
+ "@supabase/supabase-js": "^2.89.0",
45
46
  "@types/node": "^25.0.3",
46
47
  "@typescript-eslint/eslint-plugin": "^8.51.0",
47
48
  "@typescript-eslint/parser": "^8.51.0",
@@ -49,14 +50,28 @@
49
50
  "eslint": "^9.39.2",
50
51
  "eslint-config-prettier": "^10.1.8",
51
52
  "eslint-plugin-prettier": "^5.5.4",
52
- "msw": "^2.12.4",
53
- "next": "^16.1.0",
53
+ "msw": "^2.12.7",
54
+ "next": "^16.1.1",
54
55
  "prettier": "^3.7.4",
56
+ "react-native-app-auth": "^8.1.0",
55
57
  "typescript": "^5.9.3",
56
58
  "typescript-eslint": "^8.51.0",
57
59
  "vitest": "^4.0.16"
58
60
  },
59
61
  "peerDependencies": {
60
- "next": ">=13.0.0"
62
+ "@supabase/supabase-js": ">=2.0.0",
63
+ "next": ">=13.0.0",
64
+ "react-native-app-auth": ">=7.0.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "next": {
68
+ "optional": true
69
+ },
70
+ "@supabase/supabase-js": {
71
+ "optional": true
72
+ },
73
+ "react-native-app-auth": {
74
+ "optional": true
75
+ }
61
76
  }
62
77
  }