omni-sync-sdk 0.7.9 → 0.7.10
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 +159 -2
- package/dist/index.js +19 -6
- package/dist/index.mjs +19 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -903,6 +903,153 @@ interface CustomerAuthResponse {
|
|
|
903
903
|
};
|
|
904
904
|
token: string;
|
|
905
905
|
expiresAt: string;
|
|
906
|
+
requiresVerification?: boolean; // true if email verification is required
|
|
907
|
+
}
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
### Email Verification
|
|
913
|
+
|
|
914
|
+
If the store has **email verification enabled**, customers must verify their email after registration before they can fully use their account.
|
|
915
|
+
|
|
916
|
+
#### Registration with Email Verification
|
|
917
|
+
|
|
918
|
+
When `requiresVerification` is true in the registration response, the customer needs to verify their email:
|
|
919
|
+
|
|
920
|
+
```typescript
|
|
921
|
+
const auth = await omni.registerCustomer({
|
|
922
|
+
email: 'customer@example.com',
|
|
923
|
+
password: 'securepassword123',
|
|
924
|
+
firstName: 'John',
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
if (auth.requiresVerification) {
|
|
928
|
+
// Save token for verification step
|
|
929
|
+
localStorage.setItem('verificationToken', auth.token);
|
|
930
|
+
// Redirect to verification page
|
|
931
|
+
window.location.href = '/verify-email';
|
|
932
|
+
} else {
|
|
933
|
+
// No verification needed - proceed normally
|
|
934
|
+
setCustomerToken(auth.token);
|
|
935
|
+
window.location.href = '/account';
|
|
936
|
+
}
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
#### Verify Email with Code
|
|
940
|
+
|
|
941
|
+
After the customer receives the 6-digit code via email:
|
|
942
|
+
|
|
943
|
+
```typescript
|
|
944
|
+
// Get the token saved from registration
|
|
945
|
+
const token = localStorage.getItem('verificationToken');
|
|
946
|
+
|
|
947
|
+
// Verify email - pass the token directly (no need to call setCustomerToken first!)
|
|
948
|
+
const result = await omni.verifyEmail(code, token);
|
|
949
|
+
|
|
950
|
+
if (result.verified) {
|
|
951
|
+
// Email verified! Now set the token for normal use
|
|
952
|
+
setCustomerToken(token);
|
|
953
|
+
localStorage.removeItem('verificationToken');
|
|
954
|
+
window.location.href = '/account';
|
|
955
|
+
}
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
#### Resend Verification Email
|
|
959
|
+
|
|
960
|
+
If the customer didn't receive the email or the code expired:
|
|
961
|
+
|
|
962
|
+
```typescript
|
|
963
|
+
const token = localStorage.getItem('verificationToken');
|
|
964
|
+
await omni.resendVerificationEmail(token);
|
|
965
|
+
// Show success message - new code sent
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
> **Note:** Resend is rate-limited to 3 requests per hour.
|
|
969
|
+
|
|
970
|
+
#### Complete Email Verification Page Example
|
|
971
|
+
|
|
972
|
+
```typescript
|
|
973
|
+
'use client';
|
|
974
|
+
import { useState } from 'react';
|
|
975
|
+
import { omni, setCustomerToken } from '@/lib/omni-sync';
|
|
976
|
+
import { toast } from 'sonner';
|
|
977
|
+
|
|
978
|
+
export default function VerifyEmailPage() {
|
|
979
|
+
const [code, setCode] = useState('');
|
|
980
|
+
const [loading, setLoading] = useState(false);
|
|
981
|
+
|
|
982
|
+
const handleVerify = async (e: React.FormEvent) => {
|
|
983
|
+
e.preventDefault();
|
|
984
|
+
setLoading(true);
|
|
985
|
+
|
|
986
|
+
try {
|
|
987
|
+
const token = localStorage.getItem('verificationToken');
|
|
988
|
+
if (!token) {
|
|
989
|
+
toast.error('No verification token found. Please register again.');
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const result = await omni.verifyEmail(code, token);
|
|
994
|
+
|
|
995
|
+
if (result.verified) {
|
|
996
|
+
toast.success('Email verified!');
|
|
997
|
+
setCustomerToken(token);
|
|
998
|
+
localStorage.removeItem('verificationToken');
|
|
999
|
+
window.location.href = '/account';
|
|
1000
|
+
}
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
toast.error(error instanceof Error ? error.message : 'Verification failed');
|
|
1003
|
+
} finally {
|
|
1004
|
+
setLoading(false);
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
const handleResend = async () => {
|
|
1009
|
+
try {
|
|
1010
|
+
const token = localStorage.getItem('verificationToken');
|
|
1011
|
+
if (!token) {
|
|
1012
|
+
toast.error('No verification token found');
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
await omni.resendVerificationEmail(token);
|
|
1016
|
+
toast.success('Verification code sent!');
|
|
1017
|
+
} catch (error) {
|
|
1018
|
+
toast.error(error instanceof Error ? error.message : 'Failed to resend');
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
|
|
1022
|
+
return (
|
|
1023
|
+
<div className="max-w-md mx-auto mt-12">
|
|
1024
|
+
<h1 className="text-2xl font-bold mb-4">Verify Your Email</h1>
|
|
1025
|
+
<p className="text-gray-600 mb-6">
|
|
1026
|
+
We sent a 6-digit code to your email. Enter it below to verify your account.
|
|
1027
|
+
</p>
|
|
1028
|
+
|
|
1029
|
+
<form onSubmit={handleVerify} className="space-y-4">
|
|
1030
|
+
<input
|
|
1031
|
+
type="text"
|
|
1032
|
+
placeholder="Enter 6-digit code"
|
|
1033
|
+
value={code}
|
|
1034
|
+
onChange={(e) => setCode(e.target.value)}
|
|
1035
|
+
maxLength={6}
|
|
1036
|
+
className="w-full border p-3 rounded text-center text-2xl tracking-widest"
|
|
1037
|
+
required
|
|
1038
|
+
/>
|
|
1039
|
+
<button
|
|
1040
|
+
type="submit"
|
|
1041
|
+
disabled={loading || code.length !== 6}
|
|
1042
|
+
className="w-full bg-black text-white py-3 rounded disabled:opacity-50"
|
|
1043
|
+
>
|
|
1044
|
+
{loading ? 'Verifying...' : 'Verify Email'}
|
|
1045
|
+
</button>
|
|
1046
|
+
</form>
|
|
1047
|
+
|
|
1048
|
+
<button onClick={handleResend} className="mt-4 text-blue-600 text-sm">
|
|
1049
|
+
Didn't receive the code? Resend
|
|
1050
|
+
</button>
|
|
1051
|
+
</div>
|
|
1052
|
+
);
|
|
906
1053
|
}
|
|
907
1054
|
```
|
|
908
1055
|
|
|
@@ -1684,8 +1831,17 @@ export default function RegisterPage() {
|
|
|
1684
1831
|
setError('');
|
|
1685
1832
|
try {
|
|
1686
1833
|
const auth = await omni.registerCustomer({ email, password, firstName, lastName });
|
|
1687
|
-
|
|
1688
|
-
|
|
1834
|
+
|
|
1835
|
+
// Check if email verification is required
|
|
1836
|
+
if (auth.requiresVerification) {
|
|
1837
|
+
// Save token for verification step
|
|
1838
|
+
localStorage.setItem('verificationToken', auth.token);
|
|
1839
|
+
window.location.href = '/verify-email';
|
|
1840
|
+
} else {
|
|
1841
|
+
// No verification needed - proceed normally
|
|
1842
|
+
setCustomerToken(auth.token);
|
|
1843
|
+
window.location.href = '/account';
|
|
1844
|
+
}
|
|
1689
1845
|
} catch (err) {
|
|
1690
1846
|
setError('Registration failed. Email may already be in use.');
|
|
1691
1847
|
} finally {
|
|
@@ -1989,6 +2145,7 @@ When building a store, implement these pages:
|
|
|
1989
2145
|
- [ ] **Checkout** (`/checkout`) - Multi-step checkout flow
|
|
1990
2146
|
- [ ] **Login** (`/login`) - Customer login
|
|
1991
2147
|
- [ ] **Register** (`/register`) - Customer registration
|
|
2148
|
+
- [ ] **Verify Email** (`/verify-email`) - Email verification with 6-digit code (if store requires it)
|
|
1992
2149
|
- [ ] **Account** (`/account`) - Profile and order history
|
|
1993
2150
|
|
|
1994
2151
|
---
|
package/dist/index.js
CHANGED
|
@@ -1118,7 +1118,10 @@ var OmniSyncClient = class {
|
|
|
1118
1118
|
async verifyEmail(code, token) {
|
|
1119
1119
|
const effectiveToken = token || this.customerToken;
|
|
1120
1120
|
if (!effectiveToken) {
|
|
1121
|
-
throw new OmniSyncError(
|
|
1121
|
+
throw new OmniSyncError(
|
|
1122
|
+
"Customer token is required. Pass token parameter or call setCustomerToken() first.",
|
|
1123
|
+
401
|
|
1124
|
+
);
|
|
1122
1125
|
}
|
|
1123
1126
|
const originalToken = this.customerToken;
|
|
1124
1127
|
if (token) {
|
|
@@ -1126,9 +1129,13 @@ var OmniSyncClient = class {
|
|
|
1126
1129
|
}
|
|
1127
1130
|
try {
|
|
1128
1131
|
if (this.isVibeCodedMode()) {
|
|
1129
|
-
return await this.vibeCodedRequest(
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
+
return await this.vibeCodedRequest(
|
|
1133
|
+
"POST",
|
|
1134
|
+
"/customers/verify-email",
|
|
1135
|
+
{
|
|
1136
|
+
code
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1132
1139
|
}
|
|
1133
1140
|
throw new OmniSyncError("verifyEmail is only available in vibe-coded mode", 400);
|
|
1134
1141
|
} finally {
|
|
@@ -1157,7 +1164,10 @@ var OmniSyncClient = class {
|
|
|
1157
1164
|
async resendVerificationEmail(token) {
|
|
1158
1165
|
const effectiveToken = token || this.customerToken;
|
|
1159
1166
|
if (!effectiveToken) {
|
|
1160
|
-
throw new OmniSyncError(
|
|
1167
|
+
throw new OmniSyncError(
|
|
1168
|
+
"Customer token is required. Pass token parameter or call setCustomerToken() first.",
|
|
1169
|
+
401
|
|
1170
|
+
);
|
|
1161
1171
|
}
|
|
1162
1172
|
const originalToken = this.customerToken;
|
|
1163
1173
|
if (token) {
|
|
@@ -1165,7 +1175,10 @@ var OmniSyncClient = class {
|
|
|
1165
1175
|
}
|
|
1166
1176
|
try {
|
|
1167
1177
|
if (this.isVibeCodedMode()) {
|
|
1168
|
-
return await this.vibeCodedRequest(
|
|
1178
|
+
return await this.vibeCodedRequest(
|
|
1179
|
+
"POST",
|
|
1180
|
+
"/customers/resend-verification"
|
|
1181
|
+
);
|
|
1169
1182
|
}
|
|
1170
1183
|
throw new OmniSyncError("resendVerificationEmail is only available in vibe-coded mode", 400);
|
|
1171
1184
|
} finally {
|
package/dist/index.mjs
CHANGED
|
@@ -1093,7 +1093,10 @@ var OmniSyncClient = class {
|
|
|
1093
1093
|
async verifyEmail(code, token) {
|
|
1094
1094
|
const effectiveToken = token || this.customerToken;
|
|
1095
1095
|
if (!effectiveToken) {
|
|
1096
|
-
throw new OmniSyncError(
|
|
1096
|
+
throw new OmniSyncError(
|
|
1097
|
+
"Customer token is required. Pass token parameter or call setCustomerToken() first.",
|
|
1098
|
+
401
|
|
1099
|
+
);
|
|
1097
1100
|
}
|
|
1098
1101
|
const originalToken = this.customerToken;
|
|
1099
1102
|
if (token) {
|
|
@@ -1101,9 +1104,13 @@ var OmniSyncClient = class {
|
|
|
1101
1104
|
}
|
|
1102
1105
|
try {
|
|
1103
1106
|
if (this.isVibeCodedMode()) {
|
|
1104
|
-
return await this.vibeCodedRequest(
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
+
return await this.vibeCodedRequest(
|
|
1108
|
+
"POST",
|
|
1109
|
+
"/customers/verify-email",
|
|
1110
|
+
{
|
|
1111
|
+
code
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1107
1114
|
}
|
|
1108
1115
|
throw new OmniSyncError("verifyEmail is only available in vibe-coded mode", 400);
|
|
1109
1116
|
} finally {
|
|
@@ -1132,7 +1139,10 @@ var OmniSyncClient = class {
|
|
|
1132
1139
|
async resendVerificationEmail(token) {
|
|
1133
1140
|
const effectiveToken = token || this.customerToken;
|
|
1134
1141
|
if (!effectiveToken) {
|
|
1135
|
-
throw new OmniSyncError(
|
|
1142
|
+
throw new OmniSyncError(
|
|
1143
|
+
"Customer token is required. Pass token parameter or call setCustomerToken() first.",
|
|
1144
|
+
401
|
|
1145
|
+
);
|
|
1136
1146
|
}
|
|
1137
1147
|
const originalToken = this.customerToken;
|
|
1138
1148
|
if (token) {
|
|
@@ -1140,7 +1150,10 @@ var OmniSyncClient = class {
|
|
|
1140
1150
|
}
|
|
1141
1151
|
try {
|
|
1142
1152
|
if (this.isVibeCodedMode()) {
|
|
1143
|
-
return await this.vibeCodedRequest(
|
|
1153
|
+
return await this.vibeCodedRequest(
|
|
1154
|
+
"POST",
|
|
1155
|
+
"/customers/resend-verification"
|
|
1156
|
+
);
|
|
1144
1157
|
}
|
|
1145
1158
|
throw new OmniSyncError("resendVerificationEmail is only available in vibe-coded mode", 400);
|
|
1146
1159
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-sync-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|