@netlify/identity 0.1.0-alpha.9 → 0.1.1-alpha.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/README.md +118 -0
- package/dist/index.cjs +260 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -1
- package/dist/index.d.ts +42 -1
- package/dist/index.js +247 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,102 @@ getSettings(): Promise<Settings>
|
|
|
92
92
|
|
|
93
93
|
Fetches your project's Identity settings (enabled providers, autoconfirm, signup disabled). Throws `MissingIdentityError` if not configured; throws `AuthError` if the endpoint is unreachable.
|
|
94
94
|
|
|
95
|
+
#### `login`
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
login(email: string, password: string): Promise<User>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Logs in with email and password. Browser only.
|
|
102
|
+
|
|
103
|
+
#### `signup`
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
signup(email: string, password: string, data?: Record<string, unknown>): Promise<User>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Creates a new account. Emits `'login'` if autoconfirm is enabled. Browser only.
|
|
110
|
+
|
|
111
|
+
#### `logout`
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
logout(): Promise<void>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Logs out the current user and clears the session. Browser only.
|
|
118
|
+
|
|
119
|
+
#### `oauthLogin`
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
oauthLogin(provider: string): never
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Redirects to an OAuth provider. Always throws (the page navigates away). Browser only.
|
|
126
|
+
|
|
127
|
+
#### `handleAuthCallback`
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
handleAuthCallback(): Promise<CallbackResult | null>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Processes the URL hash after an OAuth redirect, email confirmation, password recovery, invite acceptance, or email change. Call on page load. Returns `null` if the hash contains no auth parameters. Browser only.
|
|
134
|
+
|
|
135
|
+
#### `onAuthChange`
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
onAuthChange(callback: AuthCallback): () => void
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Subscribes to auth state changes (login, logout, token refresh, user updates). Returns an unsubscribe function. Also fires on cross-tab session changes. No-op on the server.
|
|
142
|
+
|
|
143
|
+
#### `requestPasswordRecovery`
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
requestPasswordRecovery(email: string): Promise<void>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Sends a password recovery email to the given address.
|
|
150
|
+
|
|
151
|
+
#### `recoverPassword`
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
recoverPassword(token: string, newPassword: string): Promise<User>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Redeems a recovery token and sets a new password. Logs the user in on success.
|
|
158
|
+
|
|
159
|
+
#### `confirmEmail`
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
confirmEmail(token: string): Promise<User>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Confirms an email address using the token from a confirmation email. Logs the user in on success.
|
|
166
|
+
|
|
167
|
+
#### `acceptInvite`
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
acceptInvite(token: string, password: string): Promise<User>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Accepts an invite token and sets a password for the new account. Logs the user in on success.
|
|
174
|
+
|
|
175
|
+
#### `verifyEmailChange`
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
verifyEmailChange(token: string): Promise<User>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Verifies an email change using the token from a verification email.
|
|
182
|
+
|
|
183
|
+
#### `updateUser`
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
updateUser(updates: Record<string, unknown>): Promise<User>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Updates the current user's metadata or credentials. Requires an active session.
|
|
190
|
+
|
|
95
191
|
### Types
|
|
96
192
|
|
|
97
193
|
#### `User`
|
|
@@ -146,6 +242,28 @@ interface AppMetadata {
|
|
|
146
242
|
}
|
|
147
243
|
```
|
|
148
244
|
|
|
245
|
+
#### `AuthEvent`
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### `AuthCallback`
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
type AuthCallback = (event: AuthEvent, user: User | null) => void
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### `CallbackResult`
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
interface CallbackResult {
|
|
261
|
+
type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'
|
|
262
|
+
user: User | null
|
|
263
|
+
token?: string
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
149
267
|
### Errors
|
|
150
268
|
|
|
151
269
|
#### `AuthError`
|
package/dist/index.cjs
CHANGED
|
@@ -32,10 +32,22 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AuthError: () => AuthError,
|
|
34
34
|
MissingIdentityError: () => MissingIdentityError,
|
|
35
|
+
acceptInvite: () => acceptInvite,
|
|
36
|
+
confirmEmail: () => confirmEmail,
|
|
35
37
|
getIdentityConfig: () => getIdentityConfig,
|
|
36
38
|
getSettings: () => getSettings,
|
|
37
39
|
getUser: () => getUser,
|
|
38
|
-
|
|
40
|
+
handleAuthCallback: () => handleAuthCallback,
|
|
41
|
+
isAuthenticated: () => isAuthenticated,
|
|
42
|
+
login: () => login,
|
|
43
|
+
logout: () => logout,
|
|
44
|
+
oauthLogin: () => oauthLogin,
|
|
45
|
+
onAuthChange: () => onAuthChange,
|
|
46
|
+
recoverPassword: () => recoverPassword,
|
|
47
|
+
requestPasswordRecovery: () => requestPasswordRecovery,
|
|
48
|
+
signup: () => signup,
|
|
49
|
+
updateUser: () => updateUser,
|
|
50
|
+
verifyEmailChange: () => verifyEmailChange
|
|
39
51
|
});
|
|
40
52
|
module.exports = __toCommonJS(index_exports);
|
|
41
53
|
|
|
@@ -44,6 +56,26 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
44
56
|
|
|
45
57
|
// src/environment.ts
|
|
46
58
|
var import_gotrue_js = __toESM(require("gotrue-js"), 1);
|
|
59
|
+
|
|
60
|
+
// src/errors.ts
|
|
61
|
+
var AuthError = class extends Error {
|
|
62
|
+
constructor(message, status, options) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "AuthError";
|
|
65
|
+
this.status = status;
|
|
66
|
+
if (options && "cause" in options) {
|
|
67
|
+
this.cause = options.cause;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var MissingIdentityError = class extends Error {
|
|
72
|
+
constructor(message = "Identity is not available in this environment") {
|
|
73
|
+
super(message);
|
|
74
|
+
this.name = "MissingIdentityError";
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/environment.ts
|
|
47
79
|
var goTrueClient = null;
|
|
48
80
|
var cachedApiUrl;
|
|
49
81
|
var warnedMissingUrl = false;
|
|
@@ -77,6 +109,11 @@ var getGoTrueClient = () => {
|
|
|
77
109
|
goTrueClient = new import_gotrue_js.default({ APIUrl: apiUrl, setCookie: isBrowser() });
|
|
78
110
|
return goTrueClient;
|
|
79
111
|
};
|
|
112
|
+
var getClient = () => {
|
|
113
|
+
const client = getGoTrueClient();
|
|
114
|
+
if (!client) throw new MissingIdentityError();
|
|
115
|
+
return client;
|
|
116
|
+
};
|
|
80
117
|
var getIdentityContext = () => {
|
|
81
118
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
82
119
|
if (identityContext?.url && typeof identityContext.url === "string") {
|
|
@@ -138,24 +175,6 @@ var getUser = () => {
|
|
|
138
175
|
};
|
|
139
176
|
var isAuthenticated = () => getUser() !== null;
|
|
140
177
|
|
|
141
|
-
// src/errors.ts
|
|
142
|
-
var AuthError = class extends Error {
|
|
143
|
-
constructor(message, status, options) {
|
|
144
|
-
super(message);
|
|
145
|
-
this.name = "AuthError";
|
|
146
|
-
this.status = status;
|
|
147
|
-
if (options && "cause" in options) {
|
|
148
|
-
this.cause = options.cause;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
var MissingIdentityError = class extends Error {
|
|
153
|
-
constructor(message = "Identity is not available in this environment") {
|
|
154
|
-
super(message);
|
|
155
|
-
this.name = "MissingIdentityError";
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
|
|
159
178
|
// src/config.ts
|
|
160
179
|
var getIdentityConfig = () => {
|
|
161
180
|
if (isBrowser()) {
|
|
@@ -164,8 +183,7 @@ var getIdentityConfig = () => {
|
|
|
164
183
|
return getIdentityContext();
|
|
165
184
|
};
|
|
166
185
|
var getSettings = async () => {
|
|
167
|
-
const client =
|
|
168
|
-
if (!client) throw new MissingIdentityError();
|
|
186
|
+
const client = getClient();
|
|
169
187
|
try {
|
|
170
188
|
const raw = await client.settings();
|
|
171
189
|
const external = raw.external ?? {};
|
|
@@ -186,13 +204,233 @@ var getSettings = async () => {
|
|
|
186
204
|
throw new AuthError(err instanceof Error ? err.message : "Failed to fetch identity settings", 502, { cause: err });
|
|
187
205
|
}
|
|
188
206
|
};
|
|
207
|
+
|
|
208
|
+
// src/auth.ts
|
|
209
|
+
var persistSession = true;
|
|
210
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
211
|
+
var emitAuthEvent = (event, user) => {
|
|
212
|
+
for (const listener of listeners) {
|
|
213
|
+
listener(event, user);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
var storageListenerAttached = false;
|
|
217
|
+
var attachStorageListener = () => {
|
|
218
|
+
if (storageListenerAttached) return;
|
|
219
|
+
storageListenerAttached = true;
|
|
220
|
+
window.addEventListener("storage", (event) => {
|
|
221
|
+
if (event.key !== "gotrue.user") return;
|
|
222
|
+
if (event.newValue) {
|
|
223
|
+
const client = getGoTrueClient();
|
|
224
|
+
const currentUser = client?.currentUser();
|
|
225
|
+
emitAuthEvent("login", currentUser ? toUser(currentUser) : null);
|
|
226
|
+
} else {
|
|
227
|
+
emitAuthEvent("logout", null);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
var onAuthChange = (callback) => {
|
|
232
|
+
if (!isBrowser()) {
|
|
233
|
+
return () => {
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
listeners.add(callback);
|
|
237
|
+
attachStorageListener();
|
|
238
|
+
return () => {
|
|
239
|
+
listeners.delete(callback);
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
var login = async (email, password) => {
|
|
243
|
+
const client = getClient();
|
|
244
|
+
try {
|
|
245
|
+
const gotrueUser = await client.login(email, password, persistSession);
|
|
246
|
+
const user = toUser(gotrueUser);
|
|
247
|
+
emitAuthEvent("login", user);
|
|
248
|
+
return user;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
var signup = async (email, password, data) => {
|
|
254
|
+
const client = getClient();
|
|
255
|
+
try {
|
|
256
|
+
const response = await client.signup(email, password, data);
|
|
257
|
+
const user = toUser(response);
|
|
258
|
+
if (response.confirmed_at) {
|
|
259
|
+
emitAuthEvent("login", user);
|
|
260
|
+
}
|
|
261
|
+
return user;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
var logout = async () => {
|
|
267
|
+
const client = getClient();
|
|
268
|
+
try {
|
|
269
|
+
const currentUser = client.currentUser();
|
|
270
|
+
if (currentUser) {
|
|
271
|
+
await currentUser.logout();
|
|
272
|
+
}
|
|
273
|
+
emitAuthEvent("logout", null);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var oauthLogin = (provider) => {
|
|
279
|
+
if (!isBrowser()) {
|
|
280
|
+
throw new Error("oauthLogin() is only available in the browser");
|
|
281
|
+
}
|
|
282
|
+
const client = getClient();
|
|
283
|
+
window.location.href = client.loginExternalUrl(provider);
|
|
284
|
+
throw new Error("Redirecting to OAuth provider");
|
|
285
|
+
};
|
|
286
|
+
var handleAuthCallback = async () => {
|
|
287
|
+
if (!isBrowser()) return null;
|
|
288
|
+
const hash = window.location.hash.substring(1);
|
|
289
|
+
if (!hash) return null;
|
|
290
|
+
const client = getClient();
|
|
291
|
+
try {
|
|
292
|
+
const params = new URLSearchParams(hash);
|
|
293
|
+
const accessToken = params.get("access_token");
|
|
294
|
+
if (accessToken) {
|
|
295
|
+
const gotrueUser = await client.createUser(
|
|
296
|
+
{
|
|
297
|
+
access_token: accessToken,
|
|
298
|
+
token_type: params.get("token_type") ?? "bearer",
|
|
299
|
+
expires_in: Number(params.get("expires_in")),
|
|
300
|
+
expires_at: Number(params.get("expires_at")),
|
|
301
|
+
refresh_token: params.get("refresh_token") ?? ""
|
|
302
|
+
},
|
|
303
|
+
persistSession
|
|
304
|
+
);
|
|
305
|
+
const user = toUser(gotrueUser);
|
|
306
|
+
clearHash();
|
|
307
|
+
emitAuthEvent("login", user);
|
|
308
|
+
return { type: "oauth", user };
|
|
309
|
+
}
|
|
310
|
+
const confirmationToken = params.get("confirmation_token");
|
|
311
|
+
if (confirmationToken) {
|
|
312
|
+
const gotrueUser = await client.confirm(confirmationToken, persistSession);
|
|
313
|
+
const user = toUser(gotrueUser);
|
|
314
|
+
clearHash();
|
|
315
|
+
emitAuthEvent("login", user);
|
|
316
|
+
return { type: "confirmation", user };
|
|
317
|
+
}
|
|
318
|
+
const recoveryToken = params.get("recovery_token");
|
|
319
|
+
if (recoveryToken) {
|
|
320
|
+
const gotrueUser = await client.recover(recoveryToken, persistSession);
|
|
321
|
+
const user = toUser(gotrueUser);
|
|
322
|
+
clearHash();
|
|
323
|
+
emitAuthEvent("login", user);
|
|
324
|
+
return { type: "recovery", user };
|
|
325
|
+
}
|
|
326
|
+
const inviteToken = params.get("invite_token");
|
|
327
|
+
if (inviteToken) {
|
|
328
|
+
clearHash();
|
|
329
|
+
return { type: "invite", user: null, token: inviteToken };
|
|
330
|
+
}
|
|
331
|
+
const emailChangeToken = params.get("email_change_token");
|
|
332
|
+
if (emailChangeToken) {
|
|
333
|
+
const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
|
|
334
|
+
const user = toUser(gotrueUser);
|
|
335
|
+
clearHash();
|
|
336
|
+
emitAuthEvent("user_updated", user);
|
|
337
|
+
return { type: "email_change", user };
|
|
338
|
+
}
|
|
339
|
+
return null;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
var clearHash = () => {
|
|
345
|
+
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// src/account.ts
|
|
349
|
+
var requestPasswordRecovery = async (email) => {
|
|
350
|
+
const client = getClient();
|
|
351
|
+
try {
|
|
352
|
+
await client.requestPasswordRecovery(email);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
var recoverPassword = async (token, newPassword) => {
|
|
358
|
+
const client = getClient();
|
|
359
|
+
try {
|
|
360
|
+
const gotrueUser = await client.recover(token, persistSession);
|
|
361
|
+
const updatedUser = await gotrueUser.update({ password: newPassword });
|
|
362
|
+
const user = toUser(updatedUser);
|
|
363
|
+
emitAuthEvent("login", user);
|
|
364
|
+
return user;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
var confirmEmail = async (token) => {
|
|
370
|
+
const client = getClient();
|
|
371
|
+
try {
|
|
372
|
+
const gotrueUser = await client.confirm(token, persistSession);
|
|
373
|
+
const user = toUser(gotrueUser);
|
|
374
|
+
emitAuthEvent("login", user);
|
|
375
|
+
return user;
|
|
376
|
+
} catch (error) {
|
|
377
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
var acceptInvite = async (token, password) => {
|
|
381
|
+
const client = getClient();
|
|
382
|
+
try {
|
|
383
|
+
const gotrueUser = await client.acceptInvite(token, password, persistSession);
|
|
384
|
+
const user = toUser(gotrueUser);
|
|
385
|
+
emitAuthEvent("login", user);
|
|
386
|
+
return user;
|
|
387
|
+
} catch (error) {
|
|
388
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
var verifyEmailChange = async (token) => {
|
|
392
|
+
const client = getClient();
|
|
393
|
+
try {
|
|
394
|
+
const gotrueUser = await client.verify("email_change", token, persistSession);
|
|
395
|
+
const user = toUser(gotrueUser);
|
|
396
|
+
emitAuthEvent("user_updated", user);
|
|
397
|
+
return user;
|
|
398
|
+
} catch (error) {
|
|
399
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
var updateUser = async (updates) => {
|
|
403
|
+
const client = getClient();
|
|
404
|
+
const currentUser = client.currentUser();
|
|
405
|
+
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
406
|
+
try {
|
|
407
|
+
const updatedUser = await currentUser.update(updates);
|
|
408
|
+
const user = toUser(updatedUser);
|
|
409
|
+
emitAuthEvent("user_updated", user);
|
|
410
|
+
return user;
|
|
411
|
+
} catch (error) {
|
|
412
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
413
|
+
}
|
|
414
|
+
};
|
|
189
415
|
// Annotate the CommonJS export names for ESM import in node:
|
|
190
416
|
0 && (module.exports = {
|
|
191
417
|
AuthError,
|
|
192
418
|
MissingIdentityError,
|
|
419
|
+
acceptInvite,
|
|
420
|
+
confirmEmail,
|
|
193
421
|
getIdentityConfig,
|
|
194
422
|
getSettings,
|
|
195
423
|
getUser,
|
|
196
|
-
|
|
424
|
+
handleAuthCallback,
|
|
425
|
+
isAuthenticated,
|
|
426
|
+
login,
|
|
427
|
+
logout,
|
|
428
|
+
oauthLogin,
|
|
429
|
+
onAuthChange,
|
|
430
|
+
recoverPassword,
|
|
431
|
+
requestPasswordRecovery,
|
|
432
|
+
signup,
|
|
433
|
+
updateUser,
|
|
434
|
+
verifyEmailChange
|
|
197
435
|
});
|
|
198
436
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/user.ts","../src/errors.ts","../src/config.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError, MissingIdentityError } from './errors.js'\nimport { getGoTrueClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport {\n requestPasswordRecovery,\n recoverPassword,\n confirmEmail,\n acceptInvite,\n verifyEmailChange,\n updateUser,\n} from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Browser only. */\nexport const login = async (email: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Browser only. */\nexport const logout = async (): Promise<void> => {\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -51,6 +51,34 @@ declare const getIdentityConfig: () => IdentityConfig | null;
|
|
|
51
51
|
*/
|
|
52
52
|
declare const getSettings: () => Promise<Settings>;
|
|
53
53
|
|
|
54
|
+
type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated';
|
|
55
|
+
|
|
56
|
+
type AuthCallback = (event: AuthEvent, user: User | null) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Subscribes to auth state changes (login, logout, token refresh, user updates).
|
|
59
|
+
* Returns an unsubscribe function. No-op on the server.
|
|
60
|
+
*/
|
|
61
|
+
declare const onAuthChange: (callback: AuthCallback) => (() => void);
|
|
62
|
+
/** Logs in with email and password. Browser only. */
|
|
63
|
+
declare const login: (email: string, password: string) => Promise<User>;
|
|
64
|
+
/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */
|
|
65
|
+
declare const signup: (email: string, password: string, data?: Record<string, unknown>) => Promise<User>;
|
|
66
|
+
/** Logs out the current user and clears the session. Browser only. */
|
|
67
|
+
declare const logout: () => Promise<void>;
|
|
68
|
+
/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */
|
|
69
|
+
declare const oauthLogin: (provider: string) => never;
|
|
70
|
+
interface CallbackResult {
|
|
71
|
+
type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change';
|
|
72
|
+
user: User | null;
|
|
73
|
+
token?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Processes the URL hash after an OAuth redirect, email confirmation, password
|
|
77
|
+
* recovery, invite acceptance, or email change. Call on page load. Browser only.
|
|
78
|
+
* Returns `null` if the hash contains no auth parameters.
|
|
79
|
+
*/
|
|
80
|
+
declare const handleAuthCallback: () => Promise<CallbackResult | null>;
|
|
81
|
+
|
|
54
82
|
declare class AuthError extends Error {
|
|
55
83
|
name: string;
|
|
56
84
|
status?: number;
|
|
@@ -64,4 +92,17 @@ declare class MissingIdentityError extends Error {
|
|
|
64
92
|
constructor(message?: string);
|
|
65
93
|
}
|
|
66
94
|
|
|
67
|
-
|
|
95
|
+
/** Sends a password recovery email to the given address. */
|
|
96
|
+
declare const requestPasswordRecovery: (email: string) => Promise<void>;
|
|
97
|
+
/** Redeems a recovery token and sets a new password. Logs the user in on success. */
|
|
98
|
+
declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
|
|
99
|
+
/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
|
|
100
|
+
declare const confirmEmail: (token: string) => Promise<User>;
|
|
101
|
+
/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
|
|
102
|
+
declare const acceptInvite: (token: string, password: string) => Promise<User>;
|
|
103
|
+
/** Verifies an email change using the token from a verification email. */
|
|
104
|
+
declare const verifyEmailChange: (token: string) => Promise<User>;
|
|
105
|
+
/** Updates the current user's metadata or credentials. Requires an active session. */
|
|
106
|
+
declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
|
|
107
|
+
|
|
108
|
+
export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,34 @@ declare const getIdentityConfig: () => IdentityConfig | null;
|
|
|
51
51
|
*/
|
|
52
52
|
declare const getSettings: () => Promise<Settings>;
|
|
53
53
|
|
|
54
|
+
type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated';
|
|
55
|
+
|
|
56
|
+
type AuthCallback = (event: AuthEvent, user: User | null) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Subscribes to auth state changes (login, logout, token refresh, user updates).
|
|
59
|
+
* Returns an unsubscribe function. No-op on the server.
|
|
60
|
+
*/
|
|
61
|
+
declare const onAuthChange: (callback: AuthCallback) => (() => void);
|
|
62
|
+
/** Logs in with email and password. Browser only. */
|
|
63
|
+
declare const login: (email: string, password: string) => Promise<User>;
|
|
64
|
+
/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */
|
|
65
|
+
declare const signup: (email: string, password: string, data?: Record<string, unknown>) => Promise<User>;
|
|
66
|
+
/** Logs out the current user and clears the session. Browser only. */
|
|
67
|
+
declare const logout: () => Promise<void>;
|
|
68
|
+
/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */
|
|
69
|
+
declare const oauthLogin: (provider: string) => never;
|
|
70
|
+
interface CallbackResult {
|
|
71
|
+
type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change';
|
|
72
|
+
user: User | null;
|
|
73
|
+
token?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Processes the URL hash after an OAuth redirect, email confirmation, password
|
|
77
|
+
* recovery, invite acceptance, or email change. Call on page load. Browser only.
|
|
78
|
+
* Returns `null` if the hash contains no auth parameters.
|
|
79
|
+
*/
|
|
80
|
+
declare const handleAuthCallback: () => Promise<CallbackResult | null>;
|
|
81
|
+
|
|
54
82
|
declare class AuthError extends Error {
|
|
55
83
|
name: string;
|
|
56
84
|
status?: number;
|
|
@@ -64,4 +92,17 @@ declare class MissingIdentityError extends Error {
|
|
|
64
92
|
constructor(message?: string);
|
|
65
93
|
}
|
|
66
94
|
|
|
67
|
-
|
|
95
|
+
/** Sends a password recovery email to the given address. */
|
|
96
|
+
declare const requestPasswordRecovery: (email: string) => Promise<void>;
|
|
97
|
+
/** Redeems a recovery token and sets a new password. Logs the user in on success. */
|
|
98
|
+
declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
|
|
99
|
+
/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
|
|
100
|
+
declare const confirmEmail: (token: string) => Promise<User>;
|
|
101
|
+
/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
|
|
102
|
+
declare const acceptInvite: (token: string, password: string) => Promise<User>;
|
|
103
|
+
/** Verifies an email change using the token from a verification email. */
|
|
104
|
+
declare const verifyEmailChange: (token: string) => Promise<User>;
|
|
105
|
+
/** Updates the current user's metadata or credentials. Requires an active session. */
|
|
106
|
+
declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
|
|
107
|
+
|
|
108
|
+
export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,26 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
3
3
|
|
|
4
4
|
// src/environment.ts
|
|
5
5
|
import GoTrue from "gotrue-js";
|
|
6
|
+
|
|
7
|
+
// src/errors.ts
|
|
8
|
+
var AuthError = class extends Error {
|
|
9
|
+
constructor(message, status, options) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "AuthError";
|
|
12
|
+
this.status = status;
|
|
13
|
+
if (options && "cause" in options) {
|
|
14
|
+
this.cause = options.cause;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var MissingIdentityError = class extends Error {
|
|
19
|
+
constructor(message = "Identity is not available in this environment") {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "MissingIdentityError";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/environment.ts
|
|
6
26
|
var goTrueClient = null;
|
|
7
27
|
var cachedApiUrl;
|
|
8
28
|
var warnedMissingUrl = false;
|
|
@@ -36,6 +56,11 @@ var getGoTrueClient = () => {
|
|
|
36
56
|
goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() });
|
|
37
57
|
return goTrueClient;
|
|
38
58
|
};
|
|
59
|
+
var getClient = () => {
|
|
60
|
+
const client = getGoTrueClient();
|
|
61
|
+
if (!client) throw new MissingIdentityError();
|
|
62
|
+
return client;
|
|
63
|
+
};
|
|
39
64
|
var getIdentityContext = () => {
|
|
40
65
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
41
66
|
if (identityContext?.url && typeof identityContext.url === "string") {
|
|
@@ -97,24 +122,6 @@ var getUser = () => {
|
|
|
97
122
|
};
|
|
98
123
|
var isAuthenticated = () => getUser() !== null;
|
|
99
124
|
|
|
100
|
-
// src/errors.ts
|
|
101
|
-
var AuthError = class extends Error {
|
|
102
|
-
constructor(message, status, options) {
|
|
103
|
-
super(message);
|
|
104
|
-
this.name = "AuthError";
|
|
105
|
-
this.status = status;
|
|
106
|
-
if (options && "cause" in options) {
|
|
107
|
-
this.cause = options.cause;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
var MissingIdentityError = class extends Error {
|
|
112
|
-
constructor(message = "Identity is not available in this environment") {
|
|
113
|
-
super(message);
|
|
114
|
-
this.name = "MissingIdentityError";
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
125
|
// src/config.ts
|
|
119
126
|
var getIdentityConfig = () => {
|
|
120
127
|
if (isBrowser()) {
|
|
@@ -123,8 +130,7 @@ var getIdentityConfig = () => {
|
|
|
123
130
|
return getIdentityContext();
|
|
124
131
|
};
|
|
125
132
|
var getSettings = async () => {
|
|
126
|
-
const client =
|
|
127
|
-
if (!client) throw new MissingIdentityError();
|
|
133
|
+
const client = getClient();
|
|
128
134
|
try {
|
|
129
135
|
const raw = await client.settings();
|
|
130
136
|
const external = raw.external ?? {};
|
|
@@ -145,12 +151,232 @@ var getSettings = async () => {
|
|
|
145
151
|
throw new AuthError(err instanceof Error ? err.message : "Failed to fetch identity settings", 502, { cause: err });
|
|
146
152
|
}
|
|
147
153
|
};
|
|
154
|
+
|
|
155
|
+
// src/auth.ts
|
|
156
|
+
var persistSession = true;
|
|
157
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
158
|
+
var emitAuthEvent = (event, user) => {
|
|
159
|
+
for (const listener of listeners) {
|
|
160
|
+
listener(event, user);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var storageListenerAttached = false;
|
|
164
|
+
var attachStorageListener = () => {
|
|
165
|
+
if (storageListenerAttached) return;
|
|
166
|
+
storageListenerAttached = true;
|
|
167
|
+
window.addEventListener("storage", (event) => {
|
|
168
|
+
if (event.key !== "gotrue.user") return;
|
|
169
|
+
if (event.newValue) {
|
|
170
|
+
const client = getGoTrueClient();
|
|
171
|
+
const currentUser = client?.currentUser();
|
|
172
|
+
emitAuthEvent("login", currentUser ? toUser(currentUser) : null);
|
|
173
|
+
} else {
|
|
174
|
+
emitAuthEvent("logout", null);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
var onAuthChange = (callback) => {
|
|
179
|
+
if (!isBrowser()) {
|
|
180
|
+
return () => {
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
listeners.add(callback);
|
|
184
|
+
attachStorageListener();
|
|
185
|
+
return () => {
|
|
186
|
+
listeners.delete(callback);
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
var login = async (email, password) => {
|
|
190
|
+
const client = getClient();
|
|
191
|
+
try {
|
|
192
|
+
const gotrueUser = await client.login(email, password, persistSession);
|
|
193
|
+
const user = toUser(gotrueUser);
|
|
194
|
+
emitAuthEvent("login", user);
|
|
195
|
+
return user;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
var signup = async (email, password, data) => {
|
|
201
|
+
const client = getClient();
|
|
202
|
+
try {
|
|
203
|
+
const response = await client.signup(email, password, data);
|
|
204
|
+
const user = toUser(response);
|
|
205
|
+
if (response.confirmed_at) {
|
|
206
|
+
emitAuthEvent("login", user);
|
|
207
|
+
}
|
|
208
|
+
return user;
|
|
209
|
+
} catch (error) {
|
|
210
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var logout = async () => {
|
|
214
|
+
const client = getClient();
|
|
215
|
+
try {
|
|
216
|
+
const currentUser = client.currentUser();
|
|
217
|
+
if (currentUser) {
|
|
218
|
+
await currentUser.logout();
|
|
219
|
+
}
|
|
220
|
+
emitAuthEvent("logout", null);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
var oauthLogin = (provider) => {
|
|
226
|
+
if (!isBrowser()) {
|
|
227
|
+
throw new Error("oauthLogin() is only available in the browser");
|
|
228
|
+
}
|
|
229
|
+
const client = getClient();
|
|
230
|
+
window.location.href = client.loginExternalUrl(provider);
|
|
231
|
+
throw new Error("Redirecting to OAuth provider");
|
|
232
|
+
};
|
|
233
|
+
var handleAuthCallback = async () => {
|
|
234
|
+
if (!isBrowser()) return null;
|
|
235
|
+
const hash = window.location.hash.substring(1);
|
|
236
|
+
if (!hash) return null;
|
|
237
|
+
const client = getClient();
|
|
238
|
+
try {
|
|
239
|
+
const params = new URLSearchParams(hash);
|
|
240
|
+
const accessToken = params.get("access_token");
|
|
241
|
+
if (accessToken) {
|
|
242
|
+
const gotrueUser = await client.createUser(
|
|
243
|
+
{
|
|
244
|
+
access_token: accessToken,
|
|
245
|
+
token_type: params.get("token_type") ?? "bearer",
|
|
246
|
+
expires_in: Number(params.get("expires_in")),
|
|
247
|
+
expires_at: Number(params.get("expires_at")),
|
|
248
|
+
refresh_token: params.get("refresh_token") ?? ""
|
|
249
|
+
},
|
|
250
|
+
persistSession
|
|
251
|
+
);
|
|
252
|
+
const user = toUser(gotrueUser);
|
|
253
|
+
clearHash();
|
|
254
|
+
emitAuthEvent("login", user);
|
|
255
|
+
return { type: "oauth", user };
|
|
256
|
+
}
|
|
257
|
+
const confirmationToken = params.get("confirmation_token");
|
|
258
|
+
if (confirmationToken) {
|
|
259
|
+
const gotrueUser = await client.confirm(confirmationToken, persistSession);
|
|
260
|
+
const user = toUser(gotrueUser);
|
|
261
|
+
clearHash();
|
|
262
|
+
emitAuthEvent("login", user);
|
|
263
|
+
return { type: "confirmation", user };
|
|
264
|
+
}
|
|
265
|
+
const recoveryToken = params.get("recovery_token");
|
|
266
|
+
if (recoveryToken) {
|
|
267
|
+
const gotrueUser = await client.recover(recoveryToken, persistSession);
|
|
268
|
+
const user = toUser(gotrueUser);
|
|
269
|
+
clearHash();
|
|
270
|
+
emitAuthEvent("login", user);
|
|
271
|
+
return { type: "recovery", user };
|
|
272
|
+
}
|
|
273
|
+
const inviteToken = params.get("invite_token");
|
|
274
|
+
if (inviteToken) {
|
|
275
|
+
clearHash();
|
|
276
|
+
return { type: "invite", user: null, token: inviteToken };
|
|
277
|
+
}
|
|
278
|
+
const emailChangeToken = params.get("email_change_token");
|
|
279
|
+
if (emailChangeToken) {
|
|
280
|
+
const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
|
|
281
|
+
const user = toUser(gotrueUser);
|
|
282
|
+
clearHash();
|
|
283
|
+
emitAuthEvent("user_updated", user);
|
|
284
|
+
return { type: "email_change", user };
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
var clearHash = () => {
|
|
292
|
+
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// src/account.ts
|
|
296
|
+
var requestPasswordRecovery = async (email) => {
|
|
297
|
+
const client = getClient();
|
|
298
|
+
try {
|
|
299
|
+
await client.requestPasswordRecovery(email);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
var recoverPassword = async (token, newPassword) => {
|
|
305
|
+
const client = getClient();
|
|
306
|
+
try {
|
|
307
|
+
const gotrueUser = await client.recover(token, persistSession);
|
|
308
|
+
const updatedUser = await gotrueUser.update({ password: newPassword });
|
|
309
|
+
const user = toUser(updatedUser);
|
|
310
|
+
emitAuthEvent("login", user);
|
|
311
|
+
return user;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
var confirmEmail = async (token) => {
|
|
317
|
+
const client = getClient();
|
|
318
|
+
try {
|
|
319
|
+
const gotrueUser = await client.confirm(token, persistSession);
|
|
320
|
+
const user = toUser(gotrueUser);
|
|
321
|
+
emitAuthEvent("login", user);
|
|
322
|
+
return user;
|
|
323
|
+
} catch (error) {
|
|
324
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
var acceptInvite = async (token, password) => {
|
|
328
|
+
const client = getClient();
|
|
329
|
+
try {
|
|
330
|
+
const gotrueUser = await client.acceptInvite(token, password, persistSession);
|
|
331
|
+
const user = toUser(gotrueUser);
|
|
332
|
+
emitAuthEvent("login", user);
|
|
333
|
+
return user;
|
|
334
|
+
} catch (error) {
|
|
335
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
var verifyEmailChange = async (token) => {
|
|
339
|
+
const client = getClient();
|
|
340
|
+
try {
|
|
341
|
+
const gotrueUser = await client.verify("email_change", token, persistSession);
|
|
342
|
+
const user = toUser(gotrueUser);
|
|
343
|
+
emitAuthEvent("user_updated", user);
|
|
344
|
+
return user;
|
|
345
|
+
} catch (error) {
|
|
346
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
var updateUser = async (updates) => {
|
|
350
|
+
const client = getClient();
|
|
351
|
+
const currentUser = client.currentUser();
|
|
352
|
+
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
353
|
+
try {
|
|
354
|
+
const updatedUser = await currentUser.update(updates);
|
|
355
|
+
const user = toUser(updatedUser);
|
|
356
|
+
emitAuthEvent("user_updated", user);
|
|
357
|
+
return user;
|
|
358
|
+
} catch (error) {
|
|
359
|
+
throw new AuthError(error.message, void 0, { cause: error });
|
|
360
|
+
}
|
|
361
|
+
};
|
|
148
362
|
export {
|
|
149
363
|
AuthError,
|
|
150
364
|
MissingIdentityError,
|
|
365
|
+
acceptInvite,
|
|
366
|
+
confirmEmail,
|
|
151
367
|
getIdentityConfig,
|
|
152
368
|
getSettings,
|
|
153
369
|
getUser,
|
|
154
|
-
|
|
370
|
+
handleAuthCallback,
|
|
371
|
+
isAuthenticated,
|
|
372
|
+
login,
|
|
373
|
+
logout,
|
|
374
|
+
oauthLogin,
|
|
375
|
+
onAuthChange,
|
|
376
|
+
recoverPassword,
|
|
377
|
+
requestPasswordRecovery,
|
|
378
|
+
signup,
|
|
379
|
+
updateUser,
|
|
380
|
+
verifyEmailChange
|
|
155
381
|
};
|
|
156
382
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/user.ts","../src/errors.ts","../src/config.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError, MissingIdentityError } from './errors.js'\nimport { getGoTrueClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Browser only. */\nexport const login = async (email: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Browser only. */\nexport const logout = async (): Promise<void> => {\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":[]}
|