@sanvika/auth 2.5.9 → 2.6.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/dist/index.js +93 -40
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// SanvikaAuthProvider.jsx
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createContext,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useState,
|
|
9
|
+
useCallback,
|
|
10
|
+
useMemo
|
|
11
|
+
} from "react";
|
|
5
12
|
|
|
6
13
|
// constants.js
|
|
7
14
|
var STORAGE_KEYS = {
|
|
@@ -14,29 +21,68 @@ var DEFAULT_AVATAR_SVG = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/200
|
|
|
14
21
|
import { jsx } from "react/jsx-runtime";
|
|
15
22
|
var S_AUTH_URL = "https://accounts.sanvikaproduction.com";
|
|
16
23
|
var SanvikaAuthContext = createContext(null);
|
|
24
|
+
function randomDeviceId() {
|
|
25
|
+
try {
|
|
26
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
27
|
+
return crypto.randomUUID();
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
return `device-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
32
|
+
}
|
|
33
|
+
function createDefaultWebPersistence() {
|
|
34
|
+
return {
|
|
35
|
+
getItem: async (key) => typeof localStorage !== "undefined" ? localStorage.getItem(key) : null,
|
|
36
|
+
setItem: async (key, value) => {
|
|
37
|
+
if (typeof localStorage !== "undefined") {
|
|
38
|
+
localStorage.setItem(key, value);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
removeItem: async (key) => {
|
|
42
|
+
if (typeof localStorage !== "undefined") {
|
|
43
|
+
localStorage.removeItem(key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
17
48
|
function SanvikaAuthProvider({
|
|
18
49
|
children,
|
|
19
50
|
clientId,
|
|
20
51
|
redirectUri,
|
|
21
|
-
dashboardPath
|
|
52
|
+
dashboardPath,
|
|
53
|
+
persistence: persistenceProp
|
|
22
54
|
}) {
|
|
55
|
+
const persistence = useMemo(() => {
|
|
56
|
+
return persistenceProp || createDefaultWebPersistence();
|
|
57
|
+
}, [persistenceProp]);
|
|
23
58
|
const [user, setUser] = useState(null);
|
|
24
59
|
const [accessToken, setToken] = useState(null);
|
|
25
60
|
const [loading, setLoading] = useState(true);
|
|
26
61
|
useEffect(() => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
62
|
+
let cancelled = false;
|
|
63
|
+
(async () => {
|
|
64
|
+
try {
|
|
65
|
+
const storedToken = await persistence.getItem(STORAGE_KEYS.ACCESS_TOKEN);
|
|
66
|
+
const storedUser = await persistence.getItem(STORAGE_KEYS.USER);
|
|
67
|
+
if (cancelled) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (storedToken && storedUser) {
|
|
71
|
+
setToken(storedToken);
|
|
72
|
+
setUser(JSON.parse(storedUser));
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error("[SanvikaAuth] Failed to load session:", e);
|
|
76
|
+
} finally {
|
|
77
|
+
if (!cancelled) {
|
|
78
|
+
setLoading(false);
|
|
79
|
+
}
|
|
33
80
|
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}, []);
|
|
81
|
+
})();
|
|
82
|
+
return () => {
|
|
83
|
+
cancelled = true;
|
|
84
|
+
};
|
|
85
|
+
}, [persistence]);
|
|
40
86
|
const login = async ({ mobile, password, deviceId, deviceName }) => {
|
|
41
87
|
const response = await fetch(`${S_AUTH_URL}/api/auth/login`, {
|
|
42
88
|
method: "POST",
|
|
@@ -44,53 +90,61 @@ function SanvikaAuthProvider({
|
|
|
44
90
|
body: JSON.stringify({
|
|
45
91
|
mobile,
|
|
46
92
|
password,
|
|
47
|
-
deviceId: deviceId ||
|
|
93
|
+
deviceId: deviceId || randomDeviceId(),
|
|
48
94
|
deviceName: deviceName || "Browser"
|
|
49
95
|
})
|
|
50
96
|
});
|
|
51
97
|
const data = await response.json();
|
|
52
|
-
if (!data.success)
|
|
53
|
-
|
|
54
|
-
|
|
98
|
+
if (!data.success) {
|
|
99
|
+
throw new Error(data.error || data.message || "Login failed");
|
|
100
|
+
}
|
|
101
|
+
await persistence.setItem(STORAGE_KEYS.ACCESS_TOKEN, data.accessToken);
|
|
102
|
+
await persistence.setItem(STORAGE_KEYS.USER, JSON.stringify(data.user));
|
|
55
103
|
setToken(data.accessToken);
|
|
56
104
|
setUser(data.user);
|
|
57
105
|
return data;
|
|
58
106
|
};
|
|
59
|
-
const setAuth = (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
107
|
+
const setAuth = useCallback(
|
|
108
|
+
(token, userData) => {
|
|
109
|
+
setToken(token);
|
|
110
|
+
setUser(userData);
|
|
111
|
+
void persistence.setItem(STORAGE_KEYS.ACCESS_TOKEN, token).catch((e) => console.error("[SanvikaAuth] setAuth token persist:", e));
|
|
112
|
+
void persistence.setItem(STORAGE_KEYS.USER, JSON.stringify(userData)).catch((e) => console.error("[SanvikaAuth] setAuth user persist:", e));
|
|
113
|
+
},
|
|
114
|
+
[persistence]
|
|
115
|
+
);
|
|
65
116
|
const logout = async () => {
|
|
66
117
|
try {
|
|
67
118
|
await fetch(`${S_AUTH_URL}/api/auth/logout`, {
|
|
68
119
|
method: "POST",
|
|
69
120
|
headers: {
|
|
70
121
|
"Content-Type": "application/json",
|
|
71
|
-
Authorization: `Bearer ${accessToken}`
|
|
122
|
+
...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
|
|
72
123
|
}
|
|
73
124
|
});
|
|
74
125
|
} catch (e) {
|
|
75
126
|
console.error("[SanvikaAuth] Logout API error:", e);
|
|
76
127
|
} finally {
|
|
77
|
-
|
|
78
|
-
|
|
128
|
+
await persistence.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
|
|
129
|
+
await persistence.removeItem(STORAGE_KEYS.USER);
|
|
79
130
|
setToken(null);
|
|
80
131
|
setUser(null);
|
|
81
132
|
}
|
|
82
133
|
};
|
|
83
|
-
const authFetch = useCallback(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
134
|
+
const authFetch = useCallback(
|
|
135
|
+
async (url, opts = {}) => {
|
|
136
|
+
const currentToken = await persistence.getItem(STORAGE_KEYS.ACCESS_TOKEN);
|
|
137
|
+
const headers = {
|
|
138
|
+
"Content-Type": "application/json",
|
|
139
|
+
...currentToken && { Authorization: `Bearer ${currentToken}` },
|
|
140
|
+
...opts.headers
|
|
141
|
+
};
|
|
142
|
+
const res = await fetch(url, { ...opts, headers });
|
|
143
|
+
const data = await res.json();
|
|
144
|
+
return { data, success: data.success };
|
|
145
|
+
},
|
|
146
|
+
[persistence]
|
|
147
|
+
);
|
|
94
148
|
const value = {
|
|
95
149
|
user,
|
|
96
150
|
accessToken,
|
|
@@ -109,8 +163,7 @@ function SanvikaAuthProvider({
|
|
|
109
163
|
return /* @__PURE__ */ jsx(SanvikaAuthContext.Provider, { value, children });
|
|
110
164
|
}
|
|
111
165
|
function useSanvikaAuth() {
|
|
112
|
-
|
|
113
|
-
return ctx;
|
|
166
|
+
return useContext(SanvikaAuthContext);
|
|
114
167
|
}
|
|
115
168
|
|
|
116
169
|
// SanvikaAccountButton.jsx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanvika/auth",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Sanvika Auth SDK — React components/hooks + server-side token verification and user proxy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"next": ">=16.2.1",
|
|
24
24
|
"react": ">=18"
|
|
25
25
|
},
|
|
26
|
+
"peerDependenciesMeta": {
|
|
27
|
+
"next": {
|
|
28
|
+
"optional": true
|
|
29
|
+
}
|
|
30
|
+
},
|
|
26
31
|
"devDependencies": {
|
|
27
32
|
"tsup": "^8.5.1"
|
|
28
33
|
},
|