@mspkapps/auth-client 0.1.5 → 0.1.9

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/AuthClient.js +105 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mspkapps/auth-client",
3
- "version": "0.1.5",
3
+ "version": "0.1.9",
4
4
  "description": "Lightweight client for Your Auth Service",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/AuthClient.js CHANGED
@@ -13,10 +13,10 @@ export class AuthClient {
13
13
  baseUrl = 'https://cpanel.backend.mspkapps.in/api/v1',
14
14
  storage,
15
15
  fetch: fetchFn,
16
- keyInPath = true, // default: use headers, not key in URL
16
+ keyInPath = true,
17
17
  } = {}) {
18
18
  if (!apiKey) throw new Error('apiKey is required');
19
- if (!apiSecret) throw new Error('apiSecret is required'); // do not expose in browsers for prod
19
+ if (!apiSecret) throw new Error('apiSecret is required');
20
20
  this.apiKey = apiKey;
21
21
  this.apiSecret = apiSecret;
22
22
  this.baseUrl = baseUrl.replace(/\/$/, '');
@@ -24,7 +24,6 @@ export class AuthClient {
24
24
 
25
25
  const f = fetchFn || (typeof window !== 'undefined' ? window.fetch : (typeof fetch !== 'undefined' ? fetch : null));
26
26
  if (!f) throw new Error('No fetch available. Pass { fetch } or run on Node 18+/browsers.');
27
- // Bind to avoid “Illegal invocation”
28
27
  this.fetch = (...args) => f(...args);
29
28
 
30
29
  this.storage = storage ?? (typeof window !== 'undefined' ? window.localStorage : null);
@@ -34,8 +33,8 @@ export class AuthClient {
34
33
 
35
34
  // ---------- storage helpers ----------
36
35
  _load(key) { if (!this.storage) return null; try { return this.storage.getItem(key); } catch { return null; } }
37
- _save(key, val) { if (!this.storage) return; try { this.storage.setItem(key, val); } catch {} }
38
- _clear(key) { if (!this.storage) return; try { this.storage.removeItem(key); } catch {} }
36
+ _save(key, val) { if (!this.storage) return; try { this.storage.setItem(key, val); } catch { } }
37
+ _clear(key) { if (!this.storage) return; try { this.storage.removeItem(key); } catch { } }
39
38
 
40
39
  // ---------- internal builders ----------
41
40
  _buildUrl(path) {
@@ -92,17 +91,115 @@ export class AuthClient {
92
91
  return json;
93
92
  }
94
93
 
94
+ /**
95
+ * Google Sign-In authentication
96
+ * @param {Object} params - Google authentication parameters
97
+ * @param {string} [params.id_token] - Google ID token from credential response
98
+ * @param {string} [params.access_token] - Google access token (alternative to id_token)
99
+ * @returns {Promise<Object>} Authentication response with user data and token
100
+ * @example
101
+ * // With Google Sign-In button (React)
102
+ * import { GoogleLogin } from '@react-oauth/google';
103
+ *
104
+ * const handleSuccess = async (credentialResponse) => {
105
+ * const result = await auth.googleAuth({
106
+ * id_token: credentialResponse.credential
107
+ * });
108
+ * console.log('User:', result.data.user);
109
+ * console.log('Is new user:', result.data.is_new_user);
110
+ * };
111
+ *
112
+ * <GoogleLogin onSuccess={handleSuccess} />
113
+ */
114
+ async googleAuth({ id_token, access_token }) {
115
+ if (!id_token && !access_token) {
116
+ throw new AuthError(
117
+ 'Either id_token or access_token is required for Google authentication',
118
+ 400,
119
+ 'MISSING_TOKEN',
120
+ null
121
+ );
122
+ }
123
+
124
+ const resp = await this.fetch(this._buildUrl('auth/google'), {
125
+ method: 'POST',
126
+ headers: this._headers(),
127
+ body: JSON.stringify({ id_token, access_token })
128
+ });
129
+
130
+ const json = await safeJson(resp);
131
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Google authentication failed');
132
+
133
+ const token = json?.data?.user_token;
134
+ if (token) this.setToken(token);
135
+
136
+ return json;
137
+ }
138
+
139
+ async requestPasswordReset({ email }) {
140
+ const resp = await this.fetch(this._buildUrl('auth/request-password-reset'), {
141
+ method: 'POST',
142
+ headers: this._headers(),
143
+ body: JSON.stringify({ email })
144
+ });
145
+ const json = await safeJson(resp);
146
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Password reset request failed');
147
+ return json;
148
+ }
149
+
150
+ async changePassword({ currentPassword, newPassword }) {
151
+ const resp = await this.fetch(this._buildUrl('auth/change-password'), {
152
+ method: 'POST',
153
+ headers: this._headers(),
154
+ body: JSON.stringify({ current_password: currentPassword, new_password: newPassword })
155
+ });
156
+ const json = await safeJson(resp);
157
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Change password failed');
158
+ return json;
159
+ }
160
+
161
+ async resendVerificationEmail({ email, purpose }) {
162
+ const resp = await this.fetch(this._buildUrl('auth/resend-verification'), {
163
+ method: 'POST',
164
+ headers: this._headers(),
165
+ body: JSON.stringify({ email, purpose })
166
+ });
167
+ const json = await safeJson(resp);
168
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Resend verification failed');
169
+ return json;
170
+ }
171
+
172
+ async deleteAccount({ email, password }) {
173
+ const resp = await this.fetch(this._buildUrl('auth/delete-account'), {
174
+ method: 'POST',
175
+ headers: this._headers(),
176
+ body: JSON.stringify({ email, password })
177
+ });
178
+ const json = await safeJson(resp);
179
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Delete account failed');
180
+ return json;
181
+ }
182
+
183
+ /**
184
+ * Get current user profile (requires authentication)
185
+ * @returns {Promise<Object>} User profile data
186
+ */
95
187
  async getProfile() {
96
- const resp = await this.fetch(this._buildUrl('auth/user/profile'), {
188
+ const resp = await this.fetch(this._buildUrl('user/profile'), {
97
189
  method: 'GET',
98
190
  headers: this._headers()
99
191
  });
100
192
  const json = await safeJson(resp);
101
- if (!resp.ok || json?.success === false) throw toError(resp, json, 'Profile failed');
193
+ if (!resp.ok || json?.success === false) throw toError(resp, json, 'Get profile failed');
102
194
  return json;
103
195
  }
104
196
 
105
- // Generic authorized call for extra endpoints
197
+ /**
198
+ * Generic authorized call for custom endpoints
199
+ * @param {string} path - API endpoint path
200
+ * @param {Object} options - Request options
201
+ * @returns {Promise<Object>} Response data
202
+ */
106
203
  async authed(path, { method = 'GET', body, headers } = {}) {
107
204
  const resp = await this.fetch(this._buildUrl(path), {
108
205
  method,