@sanvika/auth 2.5.9 → 2.6.1

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 CHANGED
@@ -1,7 +1,14 @@
1
1
  "use client";
2
2
 
3
3
  // SanvikaAuthProvider.jsx
4
- import { createContext, useContext, useEffect, useState, useCallback } from "react";
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 = {
@@ -12,31 +19,70 @@ var DEFAULT_AVATAR_SVG = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/200
12
19
 
13
20
  // SanvikaAuthProvider.jsx
14
21
  import { jsx } from "react/jsx-runtime";
15
- var S_AUTH_URL = "https://accounts.sanvikaproduction.com";
22
+ var S_AUTH_URL = "https://auth.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
- try {
28
- const storedToken = localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN);
29
- const storedUser = localStorage.getItem(STORAGE_KEYS.USER);
30
- if (storedToken && storedUser) {
31
- setToken(storedToken);
32
- setUser(JSON.parse(storedUser));
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
- } catch (e) {
35
- console.error("[SanvikaAuth] Failed to load from localStorage:", e);
36
- } finally {
37
- setLoading(false);
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 || crypto.randomUUID(),
93
+ deviceId: deviceId || randomDeviceId(),
48
94
  deviceName: deviceName || "Browser"
49
95
  })
50
96
  });
51
97
  const data = await response.json();
52
- if (!data.success) throw new Error(data.error);
53
- localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, data.accessToken);
54
- localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(data.user));
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 = (token, userData) => {
60
- localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, token);
61
- localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(userData));
62
- setToken(token);
63
- setUser(userData);
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
- localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
78
- localStorage.removeItem(STORAGE_KEYS.USER);
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(async (url, opts = {}) => {
84
- const currentToken = typeof window !== "undefined" ? localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN) : null;
85
- const headers = {
86
- "Content-Type": "application/json",
87
- ...currentToken && { Authorization: `Bearer ${currentToken}` },
88
- ...opts.headers
89
- };
90
- const res = await fetch(url, { ...opts, headers });
91
- const data = await res.json();
92
- return { data, success: data.success };
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
- const ctx = useContext(SanvikaAuthContext);
113
- return ctx;
166
+ return useContext(SanvikaAuthContext);
114
167
  }
115
168
 
116
169
  // SanvikaAccountButton.jsx
@@ -143,7 +196,7 @@ styleInject("@keyframes snvk-shimmer {\n 0% {\n background-position: 200% 0;
143
196
 
144
197
  // SanvikaAccountButton.jsx
145
198
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
146
- var S_AUTH_URL2 = "https://accounts.sanvikaproduction.com";
199
+ var S_AUTH_URL2 = "https://auth.sanvikaproduction.com";
147
200
  var SanvikaAccountButtonErrorBoundary = class extends Component {
148
201
  constructor(props) {
149
202
  super(props);
@@ -251,7 +304,7 @@ function SanvikaAccountButtonContent({
251
304
  if (onLoginClick) {
252
305
  onLoginClick();
253
306
  } else {
254
- window.location.href = "https://accounts.sanvikaproduction.com/authorize";
307
+ window.location.href = "https://auth.sanvikaproduction.com/authorize";
255
308
  }
256
309
  },
257
310
  "aria-label": "Login or Sign Up",
@@ -306,7 +359,7 @@ function SanvikaAccountButtonContent({
306
359
  const imageSrc = !imgError && user.image ? user.image : DEFAULT_AVATAR_SVG;
307
360
  const handleProfileClick = () => {
308
361
  if (onProfileClick) return onProfileClick();
309
- window.location.href = (auth == null ? void 0 : auth.dashboardPath) || "https://accounts.sanvikaproduction.com/dashboard";
362
+ window.location.href = (auth == null ? void 0 : auth.dashboardPath) || "https://auth.sanvikaproduction.com/dashboard";
310
363
  };
311
364
  const handleLogout = async () => {
312
365
  await logout(false);
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const _authUrl = () => {
2
2
  var _a;
3
- return typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.AUTH_URL) || "https://accounts.sanvikaproduction.com";
3
+ return typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.AUTH_URL) || "https://auth.sanvikaproduction.com";
4
4
  };
5
5
  const _serviceKey = () => {
6
6
  var _a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanvika/auth",
3
- "version": "2.5.9",
3
+ "version": "2.6.1",
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
  },