@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.
- package/package.json +1 -1
- package/src/AuthClient.js +105 -8
package/package.json
CHANGED
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,
|
|
16
|
+
keyInPath = true,
|
|
17
17
|
} = {}) {
|
|
18
18
|
if (!apiKey) throw new Error('apiKey is required');
|
|
19
|
-
if (!apiSecret) throw new Error('apiSecret is required');
|
|
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('
|
|
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, '
|
|
193
|
+
if (!resp.ok || json?.success === false) throw toError(resp, json, 'Get profile failed');
|
|
102
194
|
return json;
|
|
103
195
|
}
|
|
104
196
|
|
|
105
|
-
|
|
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,
|