@tiquo/dom-package 1.0.0 → 1.1.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.
- package/README.md +76 -6
- package/dist/index.d.mts +154 -35
- package/dist/index.d.ts +154 -35
- package/dist/index.js +423 -105
- package/dist/index.mjs +415 -105
- package/package.json +5 -3
- package/scripts/postinstall.js +14 -0
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@ Tiquo SDK for third-party websites. Integrate authentication, customer profiles,
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Email OTP Authentication** - Secure passwordless login using email verification codes
|
|
8
|
-
- **
|
|
8
|
+
- **JWT-Based Tokens** - Secure access and refresh tokens with automatic refresh
|
|
9
9
|
- **Multi-Tab Sync** - Auth state automatically syncs across all browser tabs
|
|
10
|
+
- **Native App Integration** - WebView token injection for iOS/Android hybrid apps
|
|
10
11
|
- **Customer Flow Integration** - Embed authenticated customer flows with one line of code
|
|
11
12
|
- **Framework Agnostic** - Works with React, Vue, Svelte, or vanilla JavaScript
|
|
12
13
|
- **TypeScript Support** - Full type definitions included
|
|
@@ -85,8 +86,10 @@ Verify the OTP code and authenticate the user.
|
|
|
85
86
|
const result = await auth.verifyOTP('user@example.com', '123456');
|
|
86
87
|
// {
|
|
87
88
|
// success: true,
|
|
88
|
-
//
|
|
89
|
-
//
|
|
89
|
+
// accessToken: 'eyJhbGciOiJSUzI1NiJ9...',
|
|
90
|
+
// refreshToken: 'rt_xxx...',
|
|
91
|
+
// expiresIn: 3600,
|
|
92
|
+
// expiresAt: 1234567890000,
|
|
90
93
|
// isNewUser: false,
|
|
91
94
|
// hasCustomer: true
|
|
92
95
|
// }
|
|
@@ -480,18 +483,85 @@ try {
|
|
|
480
483
|
}
|
|
481
484
|
```
|
|
482
485
|
|
|
486
|
+
## Native App WebView Integration
|
|
487
|
+
|
|
488
|
+
When building hybrid apps with iOS/Android native + WebView, you can pass authentication tokens from the native app to the DOM package.
|
|
489
|
+
|
|
490
|
+
### Method 1: Config Parameters
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
const auth = new TiquoAuth({
|
|
494
|
+
publicKey: 'pk_dom_xxx',
|
|
495
|
+
accessToken: 'eyJhbGciOiJSUzI1NiJ9...', // From OAuth flow
|
|
496
|
+
refreshToken: 'rt_xxx...'
|
|
497
|
+
});
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Method 2: Global Variable (Native App Injects JS)
|
|
501
|
+
|
|
502
|
+
**iOS (Swift):**
|
|
503
|
+
```swift
|
|
504
|
+
let script = """
|
|
505
|
+
window.__TIQUO_INIT_TOKEN__ = {
|
|
506
|
+
accessToken: '\(accessToken)',
|
|
507
|
+
refreshToken: '\(refreshToken)'
|
|
508
|
+
};
|
|
509
|
+
"""
|
|
510
|
+
let userScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: true)
|
|
511
|
+
webView.configuration.userContentController.addUserScript(userScript)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
**Android (Kotlin):**
|
|
515
|
+
```kotlin
|
|
516
|
+
webView.evaluateJavascript("""
|
|
517
|
+
window.__TIQUO_INIT_TOKEN__ = {
|
|
518
|
+
accessToken: '$accessToken',
|
|
519
|
+
refreshToken: '$refreshToken'
|
|
520
|
+
};
|
|
521
|
+
""".trimIndent(), null)
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Method 3: URL Fragment
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
https://yoursite.com/page#access_token=eyJ...&refresh_token=rt_...
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
The DOM package automatically detects and consumes tokens from all three methods. The user will be immediately authenticated in the WebView without needing to log in again.
|
|
531
|
+
|
|
532
|
+
For complete integration examples, see the [Client API documentation](https://github.com/tiquo/tiquo-dashboard/blob/main/apps/web/docs/CLIENT_API.md).
|
|
533
|
+
|
|
534
|
+
## Token Management
|
|
535
|
+
|
|
536
|
+
The SDK uses JWT tokens for authentication:
|
|
537
|
+
|
|
538
|
+
- **Access Token**: Short-lived (1 hour), used for API requests
|
|
539
|
+
- **Refresh Token**: Long-lived (30 days), used to obtain new access tokens
|
|
540
|
+
- **Automatic Refresh**: Tokens are automatically refreshed before expiration
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
// Get tokens for manual use (advanced)
|
|
544
|
+
const accessToken = auth.getAccessToken();
|
|
545
|
+
const refreshToken = auth.getRefreshToken();
|
|
546
|
+
|
|
547
|
+
// Initialize with external tokens
|
|
548
|
+
auth.initWithTokens(accessToken, refreshToken);
|
|
549
|
+
```
|
|
550
|
+
|
|
483
551
|
## Security Considerations
|
|
484
552
|
|
|
485
553
|
- The public key is safe to expose in client-side code
|
|
486
|
-
-
|
|
554
|
+
- Tokens are stored in localStorage with automatic refresh
|
|
555
|
+
- Access tokens expire after 1 hour (automatically refreshed)
|
|
556
|
+
- Refresh tokens expire after 30 days
|
|
487
557
|
- OTP codes expire after 10 minutes
|
|
488
558
|
- Failed OTP attempts are rate limited (max 5 attempts per code)
|
|
489
559
|
|
|
490
560
|
## Support
|
|
491
561
|
|
|
492
|
-
- [Documentation](https://docs.tiquo.
|
|
562
|
+
- [Documentation](https://docs.tiquo.co/dom-package)
|
|
493
563
|
- [GitHub Issues](https://github.com/tiquo/dom-package/issues)
|
|
494
|
-
- [Support Email](mailto:support@tiquo.
|
|
564
|
+
- [Support Email](mailto:support@tiquo.co)
|
|
495
565
|
|
|
496
566
|
## License
|
|
497
567
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer User ID Cookie Utility
|
|
3
|
+
*
|
|
4
|
+
* This module handles setting a cross-subdomain cookie that stores customer user IDs.
|
|
5
|
+
* The cookie is shared across all *.tiquo.app subdomains and persists for 1 year.
|
|
6
|
+
*
|
|
7
|
+
* The cookie is NOT set if the user is logged in with Clerk (dashboard staff).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if the current user is authenticated via Clerk (dashboard staff).
|
|
11
|
+
* If they are, we should NOT set the customer cookie.
|
|
12
|
+
*/
|
|
13
|
+
declare function isClerkAuthenticated(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get the list of customer user IDs from the cookie.
|
|
16
|
+
*/
|
|
17
|
+
declare function getCustomerUserIds(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Add a customer user ID to the cookie.
|
|
20
|
+
* Does nothing if:
|
|
21
|
+
* - The user is authenticated via Clerk (dashboard staff)
|
|
22
|
+
* - The user ID is already in the cookie
|
|
23
|
+
* - Running in a non-browser environment
|
|
24
|
+
*
|
|
25
|
+
* @param userId - The user ID from the users table to add
|
|
26
|
+
*/
|
|
27
|
+
declare function addCustomerUserId(userId: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Get the pre-filled email from the customer cookie.
|
|
30
|
+
* This fetches the user's email associated with the cookie user IDs.
|
|
31
|
+
* Results are cached for 5 minutes to avoid repeated API calls.
|
|
32
|
+
*
|
|
33
|
+
* @param organizationId - The Clerk organization ID
|
|
34
|
+
* @returns Promise with email and optional name fields, or null if not found
|
|
35
|
+
*/
|
|
36
|
+
declare function getPrefilledEmailFromCookie(organizationId: string): Promise<{
|
|
37
|
+
email: string;
|
|
38
|
+
firstName?: string;
|
|
39
|
+
lastName?: string;
|
|
40
|
+
} | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Clear the cached email data.
|
|
43
|
+
* Call this when the user logs out or clears cookies.
|
|
44
|
+
*/
|
|
45
|
+
declare function clearCachedEmail(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Track customer presence when the cookie is detected.
|
|
48
|
+
* This updates the customer's online status and logs activity.
|
|
49
|
+
*
|
|
50
|
+
* @param organizationId - The Clerk organization ID
|
|
51
|
+
* @returns Promise with tracking results
|
|
52
|
+
*/
|
|
53
|
+
declare function trackCustomerPresence(organizationId: string): Promise<{
|
|
54
|
+
success: boolean;
|
|
55
|
+
results?: Array<{
|
|
56
|
+
userId: string;
|
|
57
|
+
orgCustomerId?: string;
|
|
58
|
+
customerName?: string;
|
|
59
|
+
tracked: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
error?: string;
|
|
62
|
+
}>;
|
|
63
|
+
|
|
1
64
|
/**
|
|
2
65
|
* @tiquo/dom-package
|
|
3
66
|
*
|
|
4
67
|
* Customer authentication SDK for third-party websites using Tiquo.
|
|
5
68
|
* Enables email OTP authentication without passwords.
|
|
69
|
+
* Now uses JWT tokens for authentication with automatic refresh.
|
|
6
70
|
*
|
|
7
71
|
* @example
|
|
8
72
|
* ```typescript
|
|
@@ -24,7 +88,24 @@
|
|
|
24
88
|
* // Logout
|
|
25
89
|
* await auth.logout();
|
|
26
90
|
* ```
|
|
91
|
+
*
|
|
92
|
+
* For native app WebView integration:
|
|
93
|
+
* ```typescript
|
|
94
|
+
* // Method 1: Pass token via config
|
|
95
|
+
* const auth = new TiquoAuth({
|
|
96
|
+
* publicKey: 'pk_dom_xxxxx',
|
|
97
|
+
* accessToken: 'eyJ...',
|
|
98
|
+
* refreshToken: 'rt_...'
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* // Method 2: Inject via global variable (native app injects JS)
|
|
102
|
+
* // window.__TIQUO_INIT_TOKEN__ = { accessToken: 'eyJ...', refreshToken: 'rt_...' };
|
|
103
|
+
*
|
|
104
|
+
* // Method 3: Pass via URL fragment
|
|
105
|
+
* // https://yoursite.com/#access_token=eyJ...&refresh_token=rt_...
|
|
106
|
+
* ```
|
|
27
107
|
*/
|
|
108
|
+
|
|
28
109
|
interface TiquoAuthConfig {
|
|
29
110
|
/** Public key from your Tiquo Auth DOM settings */
|
|
30
111
|
publicKey: string;
|
|
@@ -36,19 +117,52 @@ interface TiquoAuthConfig {
|
|
|
36
117
|
debug?: boolean;
|
|
37
118
|
/** Enable multi-tab session sync via BroadcastChannel (default: true) */
|
|
38
119
|
enableTabSync?: boolean;
|
|
120
|
+
/** Pre-authenticated access token (for WebView injection from native apps) */
|
|
121
|
+
accessToken?: string;
|
|
122
|
+
/** Pre-authenticated refresh token (for WebView injection from native apps) */
|
|
123
|
+
refreshToken?: string;
|
|
124
|
+
}
|
|
125
|
+
declare global {
|
|
126
|
+
interface Window {
|
|
127
|
+
__TIQUO_INIT_TOKEN__?: {
|
|
128
|
+
accessToken: string;
|
|
129
|
+
refreshToken?: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
39
132
|
}
|
|
40
133
|
interface TiquoUser {
|
|
41
134
|
id: string;
|
|
42
135
|
email: string;
|
|
43
136
|
}
|
|
137
|
+
interface TiquoCustomerEmail {
|
|
138
|
+
address: string;
|
|
139
|
+
isPrimary: boolean;
|
|
140
|
+
order: number;
|
|
141
|
+
}
|
|
142
|
+
interface TiquoCustomerPhone {
|
|
143
|
+
number: string;
|
|
144
|
+
isPrimary: boolean;
|
|
145
|
+
order: number;
|
|
146
|
+
}
|
|
44
147
|
interface TiquoCustomer {
|
|
45
148
|
id: string;
|
|
46
149
|
firstName?: string;
|
|
47
150
|
lastName?: string;
|
|
48
151
|
displayName?: string;
|
|
49
152
|
customerNumber: string;
|
|
153
|
+
/** Primary email address (convenience field derived from emails array) */
|
|
50
154
|
email?: string;
|
|
155
|
+
/** Primary phone number (convenience field derived from phones array) */
|
|
51
156
|
phone?: string;
|
|
157
|
+
profilePhoto?: string;
|
|
158
|
+
status?: string;
|
|
159
|
+
totalOrders?: number;
|
|
160
|
+
totalSpent?: number;
|
|
161
|
+
lifetimeValue?: number;
|
|
162
|
+
/** Full list of customer email addresses */
|
|
163
|
+
emails?: TiquoCustomerEmail[];
|
|
164
|
+
/** Full list of customer phone numbers */
|
|
165
|
+
phones?: TiquoCustomerPhone[];
|
|
52
166
|
}
|
|
53
167
|
interface TiquoSession {
|
|
54
168
|
user: TiquoUser;
|
|
@@ -61,7 +175,9 @@ interface SendOTPResult {
|
|
|
61
175
|
}
|
|
62
176
|
interface VerifyOTPResult {
|
|
63
177
|
success: boolean;
|
|
64
|
-
|
|
178
|
+
accessToken: string;
|
|
179
|
+
refreshToken: string;
|
|
180
|
+
expiresIn: number;
|
|
65
181
|
expiresAt: number;
|
|
66
182
|
isNewUser: boolean;
|
|
67
183
|
hasCustomer: boolean;
|
|
@@ -76,12 +192,12 @@ interface ProfileUpdateData {
|
|
|
76
192
|
displayName?: string;
|
|
77
193
|
phone?: string;
|
|
78
194
|
profilePhoto?: string;
|
|
195
|
+
emails?: TiquoCustomerEmail[];
|
|
196
|
+
phones?: TiquoCustomerPhone[];
|
|
79
197
|
}
|
|
80
198
|
interface ProfileUpdateResult {
|
|
81
199
|
success: boolean;
|
|
82
|
-
customer: TiquoCustomer
|
|
83
|
-
profilePhoto?: string;
|
|
84
|
-
};
|
|
200
|
+
customer: TiquoCustomer;
|
|
85
201
|
}
|
|
86
202
|
interface TiquoOrderItem {
|
|
87
203
|
id: string;
|
|
@@ -95,7 +211,7 @@ interface TiquoOrder {
|
|
|
95
211
|
id: string;
|
|
96
212
|
orderNumber: string;
|
|
97
213
|
status: 'draft' | 'pending' | 'confirmed' | 'processing' | 'completed' | 'cancelled' | 'refunded' | 'open_tab';
|
|
98
|
-
paymentStatus: 'pending' | 'paid' | 'partial' | 'refunded' | 'failed' | 'cancelled';
|
|
214
|
+
paymentStatus: 'pending' | 'paid' | 'partial' | 'refunded' | 'partially_refunded' | 'failed' | 'cancelled';
|
|
99
215
|
total: number;
|
|
100
216
|
subtotal: number;
|
|
101
217
|
taxTotal: number;
|
|
@@ -118,7 +234,6 @@ interface GetOrdersResult {
|
|
|
118
234
|
interface TiquoBooking {
|
|
119
235
|
id: string;
|
|
120
236
|
bookingNumber: string;
|
|
121
|
-
confirmationCode: string;
|
|
122
237
|
status: 'draft' | 'scheduled' | 'confirmed' | 'reminder_sent' | 'waiting_room' | 'waiting_list' | 'checked_in' | 'active' | 'in_progress' | 'completed' | 'cancelled' | 'no_show' | 'rescheduled';
|
|
123
238
|
date: number;
|
|
124
239
|
startTime: string;
|
|
@@ -181,10 +296,12 @@ declare class TiquoAuthError extends Error {
|
|
|
181
296
|
}
|
|
182
297
|
declare class TiquoAuth {
|
|
183
298
|
private config;
|
|
184
|
-
private
|
|
299
|
+
private accessToken;
|
|
300
|
+
private refreshToken;
|
|
185
301
|
private session;
|
|
186
302
|
private listeners;
|
|
187
303
|
private refreshTimer;
|
|
304
|
+
private isRefreshing;
|
|
188
305
|
private broadcastChannel;
|
|
189
306
|
private tabId;
|
|
190
307
|
private isProcessingTabSync;
|
|
@@ -251,14 +368,38 @@ declare class TiquoAuth {
|
|
|
251
368
|
onError?: (error: Error) => void;
|
|
252
369
|
}): Promise<HTMLIFrameElement>;
|
|
253
370
|
/**
|
|
254
|
-
* Get the current
|
|
371
|
+
* Get the current access token (for advanced use cases)
|
|
372
|
+
*/
|
|
373
|
+
getAccessToken(): string | null;
|
|
374
|
+
/**
|
|
375
|
+
* Get the current refresh token (for advanced use cases)
|
|
376
|
+
*/
|
|
377
|
+
getRefreshToken(): string | null;
|
|
378
|
+
/**
|
|
379
|
+
* Initialize with external tokens (for WebView integration)
|
|
380
|
+
*/
|
|
381
|
+
initWithTokens(accessToken: string, refreshToken?: string): void;
|
|
382
|
+
/**
|
|
383
|
+
* Check for tokens injected by native apps (WebView integration)
|
|
255
384
|
*/
|
|
256
|
-
|
|
385
|
+
private checkForInjectedTokens;
|
|
257
386
|
private request;
|
|
387
|
+
/**
|
|
388
|
+
* Ensure we have a valid access token, refreshing if necessary
|
|
389
|
+
*/
|
|
390
|
+
private ensureValidToken;
|
|
391
|
+
/**
|
|
392
|
+
* Refresh the access token if it's expired or about to expire
|
|
393
|
+
*/
|
|
394
|
+
private refreshTokenIfNeeded;
|
|
395
|
+
/**
|
|
396
|
+
* Perform the actual token refresh
|
|
397
|
+
*/
|
|
398
|
+
private performTokenRefresh;
|
|
258
399
|
private refreshSession;
|
|
259
|
-
private
|
|
260
|
-
private
|
|
261
|
-
private
|
|
400
|
+
private saveTokens;
|
|
401
|
+
private restoreTokens;
|
|
402
|
+
private clearTokens;
|
|
262
403
|
private notifyListeners;
|
|
263
404
|
private scheduleRefresh;
|
|
264
405
|
private log;
|
|
@@ -274,28 +415,6 @@ declare class TiquoAuth {
|
|
|
274
415
|
/**
|
|
275
416
|
* React hook for using TiquoAuth
|
|
276
417
|
* Note: Requires a TiquoAuth instance to be passed in
|
|
277
|
-
*
|
|
278
|
-
* @example
|
|
279
|
-
* ```tsx
|
|
280
|
-
* const auth = new TiquoAuth({ publicKey: 'pk_dom_xxx' });
|
|
281
|
-
*
|
|
282
|
-
* function App() {
|
|
283
|
-
* const { user, isLoading, isAuthenticated, logout } = useTiquoAuth(auth);
|
|
284
|
-
*
|
|
285
|
-
* if (isLoading) return <div>Loading...</div>;
|
|
286
|
-
*
|
|
287
|
-
* if (!isAuthenticated) {
|
|
288
|
-
* return <LoginForm auth={auth} />;
|
|
289
|
-
* }
|
|
290
|
-
*
|
|
291
|
-
* return (
|
|
292
|
-
* <div>
|
|
293
|
-
* Welcome, {user?.email}
|
|
294
|
-
* <button onClick={logout}>Logout</button>
|
|
295
|
-
* </div>
|
|
296
|
-
* );
|
|
297
|
-
* }
|
|
298
|
-
* ```
|
|
299
418
|
*/
|
|
300
419
|
declare function useTiquoAuth(auth: TiquoAuth): {
|
|
301
420
|
readonly user: TiquoUser | null;
|
|
@@ -320,4 +439,4 @@ declare function useTiquoAuth(auth: TiquoAuth): {
|
|
|
320
439
|
onAuthStateChange: (cb: AuthStateChangeCallback) => () => void;
|
|
321
440
|
};
|
|
322
441
|
|
|
323
|
-
export { type AuthStateChangeCallback, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, type TiquoSession, type TiquoUser, type VerifyOTPResult, TiquoAuth as default, useTiquoAuth };
|
|
442
|
+
export { type AuthStateChangeCallback, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isClerkAuthenticated, trackCustomerPresence, useTiquoAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer User ID Cookie Utility
|
|
3
|
+
*
|
|
4
|
+
* This module handles setting a cross-subdomain cookie that stores customer user IDs.
|
|
5
|
+
* The cookie is shared across all *.tiquo.app subdomains and persists for 1 year.
|
|
6
|
+
*
|
|
7
|
+
* The cookie is NOT set if the user is logged in with Clerk (dashboard staff).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if the current user is authenticated via Clerk (dashboard staff).
|
|
11
|
+
* If they are, we should NOT set the customer cookie.
|
|
12
|
+
*/
|
|
13
|
+
declare function isClerkAuthenticated(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get the list of customer user IDs from the cookie.
|
|
16
|
+
*/
|
|
17
|
+
declare function getCustomerUserIds(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Add a customer user ID to the cookie.
|
|
20
|
+
* Does nothing if:
|
|
21
|
+
* - The user is authenticated via Clerk (dashboard staff)
|
|
22
|
+
* - The user ID is already in the cookie
|
|
23
|
+
* - Running in a non-browser environment
|
|
24
|
+
*
|
|
25
|
+
* @param userId - The user ID from the users table to add
|
|
26
|
+
*/
|
|
27
|
+
declare function addCustomerUserId(userId: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Get the pre-filled email from the customer cookie.
|
|
30
|
+
* This fetches the user's email associated with the cookie user IDs.
|
|
31
|
+
* Results are cached for 5 minutes to avoid repeated API calls.
|
|
32
|
+
*
|
|
33
|
+
* @param organizationId - The Clerk organization ID
|
|
34
|
+
* @returns Promise with email and optional name fields, or null if not found
|
|
35
|
+
*/
|
|
36
|
+
declare function getPrefilledEmailFromCookie(organizationId: string): Promise<{
|
|
37
|
+
email: string;
|
|
38
|
+
firstName?: string;
|
|
39
|
+
lastName?: string;
|
|
40
|
+
} | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Clear the cached email data.
|
|
43
|
+
* Call this when the user logs out or clears cookies.
|
|
44
|
+
*/
|
|
45
|
+
declare function clearCachedEmail(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Track customer presence when the cookie is detected.
|
|
48
|
+
* This updates the customer's online status and logs activity.
|
|
49
|
+
*
|
|
50
|
+
* @param organizationId - The Clerk organization ID
|
|
51
|
+
* @returns Promise with tracking results
|
|
52
|
+
*/
|
|
53
|
+
declare function trackCustomerPresence(organizationId: string): Promise<{
|
|
54
|
+
success: boolean;
|
|
55
|
+
results?: Array<{
|
|
56
|
+
userId: string;
|
|
57
|
+
orgCustomerId?: string;
|
|
58
|
+
customerName?: string;
|
|
59
|
+
tracked: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
error?: string;
|
|
62
|
+
}>;
|
|
63
|
+
|
|
1
64
|
/**
|
|
2
65
|
* @tiquo/dom-package
|
|
3
66
|
*
|
|
4
67
|
* Customer authentication SDK for third-party websites using Tiquo.
|
|
5
68
|
* Enables email OTP authentication without passwords.
|
|
69
|
+
* Now uses JWT tokens for authentication with automatic refresh.
|
|
6
70
|
*
|
|
7
71
|
* @example
|
|
8
72
|
* ```typescript
|
|
@@ -24,7 +88,24 @@
|
|
|
24
88
|
* // Logout
|
|
25
89
|
* await auth.logout();
|
|
26
90
|
* ```
|
|
91
|
+
*
|
|
92
|
+
* For native app WebView integration:
|
|
93
|
+
* ```typescript
|
|
94
|
+
* // Method 1: Pass token via config
|
|
95
|
+
* const auth = new TiquoAuth({
|
|
96
|
+
* publicKey: 'pk_dom_xxxxx',
|
|
97
|
+
* accessToken: 'eyJ...',
|
|
98
|
+
* refreshToken: 'rt_...'
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* // Method 2: Inject via global variable (native app injects JS)
|
|
102
|
+
* // window.__TIQUO_INIT_TOKEN__ = { accessToken: 'eyJ...', refreshToken: 'rt_...' };
|
|
103
|
+
*
|
|
104
|
+
* // Method 3: Pass via URL fragment
|
|
105
|
+
* // https://yoursite.com/#access_token=eyJ...&refresh_token=rt_...
|
|
106
|
+
* ```
|
|
27
107
|
*/
|
|
108
|
+
|
|
28
109
|
interface TiquoAuthConfig {
|
|
29
110
|
/** Public key from your Tiquo Auth DOM settings */
|
|
30
111
|
publicKey: string;
|
|
@@ -36,19 +117,52 @@ interface TiquoAuthConfig {
|
|
|
36
117
|
debug?: boolean;
|
|
37
118
|
/** Enable multi-tab session sync via BroadcastChannel (default: true) */
|
|
38
119
|
enableTabSync?: boolean;
|
|
120
|
+
/** Pre-authenticated access token (for WebView injection from native apps) */
|
|
121
|
+
accessToken?: string;
|
|
122
|
+
/** Pre-authenticated refresh token (for WebView injection from native apps) */
|
|
123
|
+
refreshToken?: string;
|
|
124
|
+
}
|
|
125
|
+
declare global {
|
|
126
|
+
interface Window {
|
|
127
|
+
__TIQUO_INIT_TOKEN__?: {
|
|
128
|
+
accessToken: string;
|
|
129
|
+
refreshToken?: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
39
132
|
}
|
|
40
133
|
interface TiquoUser {
|
|
41
134
|
id: string;
|
|
42
135
|
email: string;
|
|
43
136
|
}
|
|
137
|
+
interface TiquoCustomerEmail {
|
|
138
|
+
address: string;
|
|
139
|
+
isPrimary: boolean;
|
|
140
|
+
order: number;
|
|
141
|
+
}
|
|
142
|
+
interface TiquoCustomerPhone {
|
|
143
|
+
number: string;
|
|
144
|
+
isPrimary: boolean;
|
|
145
|
+
order: number;
|
|
146
|
+
}
|
|
44
147
|
interface TiquoCustomer {
|
|
45
148
|
id: string;
|
|
46
149
|
firstName?: string;
|
|
47
150
|
lastName?: string;
|
|
48
151
|
displayName?: string;
|
|
49
152
|
customerNumber: string;
|
|
153
|
+
/** Primary email address (convenience field derived from emails array) */
|
|
50
154
|
email?: string;
|
|
155
|
+
/** Primary phone number (convenience field derived from phones array) */
|
|
51
156
|
phone?: string;
|
|
157
|
+
profilePhoto?: string;
|
|
158
|
+
status?: string;
|
|
159
|
+
totalOrders?: number;
|
|
160
|
+
totalSpent?: number;
|
|
161
|
+
lifetimeValue?: number;
|
|
162
|
+
/** Full list of customer email addresses */
|
|
163
|
+
emails?: TiquoCustomerEmail[];
|
|
164
|
+
/** Full list of customer phone numbers */
|
|
165
|
+
phones?: TiquoCustomerPhone[];
|
|
52
166
|
}
|
|
53
167
|
interface TiquoSession {
|
|
54
168
|
user: TiquoUser;
|
|
@@ -61,7 +175,9 @@ interface SendOTPResult {
|
|
|
61
175
|
}
|
|
62
176
|
interface VerifyOTPResult {
|
|
63
177
|
success: boolean;
|
|
64
|
-
|
|
178
|
+
accessToken: string;
|
|
179
|
+
refreshToken: string;
|
|
180
|
+
expiresIn: number;
|
|
65
181
|
expiresAt: number;
|
|
66
182
|
isNewUser: boolean;
|
|
67
183
|
hasCustomer: boolean;
|
|
@@ -76,12 +192,12 @@ interface ProfileUpdateData {
|
|
|
76
192
|
displayName?: string;
|
|
77
193
|
phone?: string;
|
|
78
194
|
profilePhoto?: string;
|
|
195
|
+
emails?: TiquoCustomerEmail[];
|
|
196
|
+
phones?: TiquoCustomerPhone[];
|
|
79
197
|
}
|
|
80
198
|
interface ProfileUpdateResult {
|
|
81
199
|
success: boolean;
|
|
82
|
-
customer: TiquoCustomer
|
|
83
|
-
profilePhoto?: string;
|
|
84
|
-
};
|
|
200
|
+
customer: TiquoCustomer;
|
|
85
201
|
}
|
|
86
202
|
interface TiquoOrderItem {
|
|
87
203
|
id: string;
|
|
@@ -95,7 +211,7 @@ interface TiquoOrder {
|
|
|
95
211
|
id: string;
|
|
96
212
|
orderNumber: string;
|
|
97
213
|
status: 'draft' | 'pending' | 'confirmed' | 'processing' | 'completed' | 'cancelled' | 'refunded' | 'open_tab';
|
|
98
|
-
paymentStatus: 'pending' | 'paid' | 'partial' | 'refunded' | 'failed' | 'cancelled';
|
|
214
|
+
paymentStatus: 'pending' | 'paid' | 'partial' | 'refunded' | 'partially_refunded' | 'failed' | 'cancelled';
|
|
99
215
|
total: number;
|
|
100
216
|
subtotal: number;
|
|
101
217
|
taxTotal: number;
|
|
@@ -118,7 +234,6 @@ interface GetOrdersResult {
|
|
|
118
234
|
interface TiquoBooking {
|
|
119
235
|
id: string;
|
|
120
236
|
bookingNumber: string;
|
|
121
|
-
confirmationCode: string;
|
|
122
237
|
status: 'draft' | 'scheduled' | 'confirmed' | 'reminder_sent' | 'waiting_room' | 'waiting_list' | 'checked_in' | 'active' | 'in_progress' | 'completed' | 'cancelled' | 'no_show' | 'rescheduled';
|
|
123
238
|
date: number;
|
|
124
239
|
startTime: string;
|
|
@@ -181,10 +296,12 @@ declare class TiquoAuthError extends Error {
|
|
|
181
296
|
}
|
|
182
297
|
declare class TiquoAuth {
|
|
183
298
|
private config;
|
|
184
|
-
private
|
|
299
|
+
private accessToken;
|
|
300
|
+
private refreshToken;
|
|
185
301
|
private session;
|
|
186
302
|
private listeners;
|
|
187
303
|
private refreshTimer;
|
|
304
|
+
private isRefreshing;
|
|
188
305
|
private broadcastChannel;
|
|
189
306
|
private tabId;
|
|
190
307
|
private isProcessingTabSync;
|
|
@@ -251,14 +368,38 @@ declare class TiquoAuth {
|
|
|
251
368
|
onError?: (error: Error) => void;
|
|
252
369
|
}): Promise<HTMLIFrameElement>;
|
|
253
370
|
/**
|
|
254
|
-
* Get the current
|
|
371
|
+
* Get the current access token (for advanced use cases)
|
|
372
|
+
*/
|
|
373
|
+
getAccessToken(): string | null;
|
|
374
|
+
/**
|
|
375
|
+
* Get the current refresh token (for advanced use cases)
|
|
376
|
+
*/
|
|
377
|
+
getRefreshToken(): string | null;
|
|
378
|
+
/**
|
|
379
|
+
* Initialize with external tokens (for WebView integration)
|
|
380
|
+
*/
|
|
381
|
+
initWithTokens(accessToken: string, refreshToken?: string): void;
|
|
382
|
+
/**
|
|
383
|
+
* Check for tokens injected by native apps (WebView integration)
|
|
255
384
|
*/
|
|
256
|
-
|
|
385
|
+
private checkForInjectedTokens;
|
|
257
386
|
private request;
|
|
387
|
+
/**
|
|
388
|
+
* Ensure we have a valid access token, refreshing if necessary
|
|
389
|
+
*/
|
|
390
|
+
private ensureValidToken;
|
|
391
|
+
/**
|
|
392
|
+
* Refresh the access token if it's expired or about to expire
|
|
393
|
+
*/
|
|
394
|
+
private refreshTokenIfNeeded;
|
|
395
|
+
/**
|
|
396
|
+
* Perform the actual token refresh
|
|
397
|
+
*/
|
|
398
|
+
private performTokenRefresh;
|
|
258
399
|
private refreshSession;
|
|
259
|
-
private
|
|
260
|
-
private
|
|
261
|
-
private
|
|
400
|
+
private saveTokens;
|
|
401
|
+
private restoreTokens;
|
|
402
|
+
private clearTokens;
|
|
262
403
|
private notifyListeners;
|
|
263
404
|
private scheduleRefresh;
|
|
264
405
|
private log;
|
|
@@ -274,28 +415,6 @@ declare class TiquoAuth {
|
|
|
274
415
|
/**
|
|
275
416
|
* React hook for using TiquoAuth
|
|
276
417
|
* Note: Requires a TiquoAuth instance to be passed in
|
|
277
|
-
*
|
|
278
|
-
* @example
|
|
279
|
-
* ```tsx
|
|
280
|
-
* const auth = new TiquoAuth({ publicKey: 'pk_dom_xxx' });
|
|
281
|
-
*
|
|
282
|
-
* function App() {
|
|
283
|
-
* const { user, isLoading, isAuthenticated, logout } = useTiquoAuth(auth);
|
|
284
|
-
*
|
|
285
|
-
* if (isLoading) return <div>Loading...</div>;
|
|
286
|
-
*
|
|
287
|
-
* if (!isAuthenticated) {
|
|
288
|
-
* return <LoginForm auth={auth} />;
|
|
289
|
-
* }
|
|
290
|
-
*
|
|
291
|
-
* return (
|
|
292
|
-
* <div>
|
|
293
|
-
* Welcome, {user?.email}
|
|
294
|
-
* <button onClick={logout}>Logout</button>
|
|
295
|
-
* </div>
|
|
296
|
-
* );
|
|
297
|
-
* }
|
|
298
|
-
* ```
|
|
299
418
|
*/
|
|
300
419
|
declare function useTiquoAuth(auth: TiquoAuth): {
|
|
301
420
|
readonly user: TiquoUser | null;
|
|
@@ -320,4 +439,4 @@ declare function useTiquoAuth(auth: TiquoAuth): {
|
|
|
320
439
|
onAuthStateChange: (cb: AuthStateChangeCallback) => () => void;
|
|
321
440
|
};
|
|
322
441
|
|
|
323
|
-
export { type AuthStateChangeCallback, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, type TiquoSession, type TiquoUser, type VerifyOTPResult, TiquoAuth as default, useTiquoAuth };
|
|
442
|
+
export { type AuthStateChangeCallback, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isClerkAuthenticated, trackCustomerPresence, useTiquoAuth };
|