najm-auth 2.0.1 → 2.0.3
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 +742 -656
- package/dist/{NajmAuthClient-D08--i69.d.ts → NajmAuthClient-B9dGk9MH.d.ts} +12 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +49 -0
- package/dist/client/react/index.d.ts +41 -2
- package/dist/client/react/index.js +129 -5
- package/dist/client/server/index.d.ts +1 -1
- package/dist/client/server/index.js +49 -0
- package/dist/index.d.ts +98 -7
- package/dist/index.js +1138 -323
- package/dist/schema/pg.d.ts +222 -1
- package/dist/schema/pg.js +13 -1
- package/dist/schema/sqlite.d.ts +246 -1
- package/dist/schema/sqlite.js +12 -0
- package/package.json +13 -10
|
@@ -77,6 +77,11 @@ interface AuthClientConfig {
|
|
|
77
77
|
/** Request timeout in milliseconds (default: 30000) */
|
|
78
78
|
timeout?: number;
|
|
79
79
|
}
|
|
80
|
+
type OAuthProvider = 'google';
|
|
81
|
+
interface OAuthLoginOptions {
|
|
82
|
+
/** Same-origin frontend path after OAuth completes. */
|
|
83
|
+
returnTo?: string;
|
|
84
|
+
}
|
|
80
85
|
/**
|
|
81
86
|
* Auth event types
|
|
82
87
|
*/
|
|
@@ -182,6 +187,11 @@ declare class NajmAuthClient {
|
|
|
182
187
|
password: string;
|
|
183
188
|
}): Promise<AuthUser>;
|
|
184
189
|
register(data: Record<string, unknown>): Promise<AuthUser>;
|
|
190
|
+
getOAuthLoginUrl(provider: OAuthProvider, options?: OAuthLoginOptions): string;
|
|
191
|
+
loginWithOAuth(provider: OAuthProvider, options?: OAuthLoginOptions): void;
|
|
192
|
+
loginWithGoogle(options?: OAuthLoginOptions): void;
|
|
193
|
+
linkOAuthAccount(provider: OAuthProvider, options?: OAuthLoginOptions): Promise<void>;
|
|
194
|
+
completeOAuthLogin(): Promise<AuthUser>;
|
|
185
195
|
logout(): Promise<void>;
|
|
186
196
|
refresh(): Promise<void>;
|
|
187
197
|
fetchUser(): Promise<AuthUser | null>;
|
|
@@ -230,10 +240,11 @@ declare class NajmAuthClient {
|
|
|
230
240
|
private handleTabMessage;
|
|
231
241
|
private notify;
|
|
232
242
|
private emit;
|
|
243
|
+
private validateReturnTo;
|
|
233
244
|
}
|
|
234
245
|
/**
|
|
235
246
|
* Factory function to create an auth client.
|
|
236
247
|
*/
|
|
237
248
|
declare function createAuthClient(config: AuthClientConfig): NajmAuthClient;
|
|
238
249
|
|
|
239
|
-
export { AuthError as A, type DecodedToken as D, FetchClient as F, type HydrateSession as H, NajmAuthClient as N, type RetryConfig as R, type SyncPayload as S, type TabSyncMessage as T, type AuthClientConfig as a, type AuthEventMap as b, createAuthClient as c, type AuthState as d, type AuthUser as e, type AuthEvent as f, type AuthEventHandler as g, type ServerResponse as h, type TokenPair as i, type RequestOptions as j };
|
|
250
|
+
export { AuthError as A, type DecodedToken as D, FetchClient as F, type HydrateSession as H, NajmAuthClient as N, type OAuthProvider as O, type RetryConfig as R, type SyncPayload as S, type TabSyncMessage as T, type AuthClientConfig as a, type AuthEventMap as b, createAuthClient as c, type AuthState as d, type AuthUser as e, type AuthEvent as f, type AuthEventHandler as g, type ServerResponse as h, type TokenPair as i, type RequestOptions as j, type OAuthLoginOptions as k };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DecodedToken, T as TabSyncMessage, S as SyncPayload } from '../NajmAuthClient-
|
|
2
|
-
export { a as AuthClientConfig, A as AuthError, f as AuthEvent, g as AuthEventHandler, b as AuthEventMap, d as AuthState, e as AuthUser, F as FetchClient, H as HydrateSession, N as NajmAuthClient, j as RequestOptions, R as RetryConfig, h as ServerResponse, i as TokenPair, c as createAuthClient } from '../NajmAuthClient-
|
|
1
|
+
import { D as DecodedToken, T as TabSyncMessage, S as SyncPayload } from '../NajmAuthClient-B9dGk9MH.js';
|
|
2
|
+
export { a as AuthClientConfig, A as AuthError, f as AuthEvent, g as AuthEventHandler, b as AuthEventMap, d as AuthState, e as AuthUser, F as FetchClient, H as HydrateSession, N as NajmAuthClient, k as OAuthLoginOptions, O as OAuthProvider, j as RequestOptions, R as RetryConfig, h as ServerResponse, i as TokenPair, c as createAuthClient } from '../NajmAuthClient-B9dGk9MH.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Decode a JWT token payload without verification.
|
package/dist/client/index.js
CHANGED
|
@@ -264,6 +264,43 @@ var NajmAuthClient = class _NajmAuthClient {
|
|
|
264
264
|
);
|
|
265
265
|
return res.data;
|
|
266
266
|
}
|
|
267
|
+
getOAuthLoginUrl(provider, options = {}) {
|
|
268
|
+
const baseURL = this.config.baseURL.replace(/\/$/, "");
|
|
269
|
+
const authPrefix = this.prefix.startsWith("/") ? this.prefix : `/${this.prefix}`;
|
|
270
|
+
const raw = `${baseURL}${authPrefix}/oauth/${provider}/start`;
|
|
271
|
+
const absolute = /^[a-z][a-z\d+.-]*:\/\//i.test(raw);
|
|
272
|
+
const url = new URL(raw, absolute ? void 0 : "https://najm.invalid");
|
|
273
|
+
if (options.returnTo) {
|
|
274
|
+
url.searchParams.set("returnTo", this.validateReturnTo(options.returnTo));
|
|
275
|
+
}
|
|
276
|
+
return absolute ? url.toString() : `${url.pathname}${url.search}`;
|
|
277
|
+
}
|
|
278
|
+
loginWithOAuth(provider, options) {
|
|
279
|
+
if (typeof window === "undefined") {
|
|
280
|
+
throw new Error("OAuth login requires a browser environment");
|
|
281
|
+
}
|
|
282
|
+
window.location.assign(this.getOAuthLoginUrl(provider, options));
|
|
283
|
+
}
|
|
284
|
+
loginWithGoogle(options) {
|
|
285
|
+
this.loginWithOAuth("google", options);
|
|
286
|
+
}
|
|
287
|
+
async linkOAuthAccount(provider, options = {}) {
|
|
288
|
+
const query = options.returnTo ? `?${new URLSearchParams({ returnTo: this.validateReturnTo(options.returnTo) })}` : "";
|
|
289
|
+
const res = await this.api.post(
|
|
290
|
+
`${this.prefix}/oauth/${provider}/link${query}`
|
|
291
|
+
);
|
|
292
|
+
if (!res.data?.authorizationUrl) throw new Error("OAuth provider did not return an authorization URL");
|
|
293
|
+
if (typeof window === "undefined") throw new Error("OAuth linking requires a browser environment");
|
|
294
|
+
window.location.assign(res.data.authorizationUrl);
|
|
295
|
+
}
|
|
296
|
+
async completeOAuthLogin() {
|
|
297
|
+
await this.refresh();
|
|
298
|
+
const user = await this.fetchUser();
|
|
299
|
+
if (!user) throw new Error("OAuth session could not be completed");
|
|
300
|
+
this.tabSync?.broadcastSync(this.getSyncPayload());
|
|
301
|
+
this.emit("login", user);
|
|
302
|
+
return user;
|
|
303
|
+
}
|
|
267
304
|
async logout() {
|
|
268
305
|
this.resetState();
|
|
269
306
|
this.tabSync?.broadcastLogout();
|
|
@@ -555,6 +592,18 @@ var NajmAuthClient = class _NajmAuthClient {
|
|
|
555
592
|
this.eventListeners.get("stateChange")?.forEach((h) => h(this.state));
|
|
556
593
|
}
|
|
557
594
|
}
|
|
595
|
+
validateReturnTo(value) {
|
|
596
|
+
const candidate = value.trim();
|
|
597
|
+
if (!candidate.startsWith("/") || candidate.startsWith("//") || candidate.includes("\\")) {
|
|
598
|
+
throw new Error("returnTo must be a same-origin path");
|
|
599
|
+
}
|
|
600
|
+
const base = new URL("https://najm.invalid");
|
|
601
|
+
const parsed = new URL(candidate, base);
|
|
602
|
+
if (parsed.origin !== base.origin || parsed.username || parsed.password) {
|
|
603
|
+
throw new Error("returnTo must be a same-origin path");
|
|
604
|
+
}
|
|
605
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
606
|
+
}
|
|
558
607
|
};
|
|
559
608
|
function createAuthClient(config) {
|
|
560
609
|
return new NajmAuthClient(config);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, CSSProperties, ReactElement } from 'react';
|
|
4
|
-
import { N as NajmAuthClient, H as HydrateSession, d as AuthState, e as AuthUser, A as AuthError, f as AuthEvent, b as AuthEventMap } from '../../NajmAuthClient-
|
|
4
|
+
import { N as NajmAuthClient, H as HydrateSession, d as AuthState, e as AuthUser, A as AuthError, k as OAuthLoginOptions, f as AuthEvent, b as AuthEventMap } from '../../NajmAuthClient-B9dGk9MH.js';
|
|
5
5
|
|
|
6
6
|
interface AuthProviderProps {
|
|
7
7
|
client: NajmAuthClient;
|
|
@@ -162,6 +162,27 @@ interface UseChangePasswordReturn {
|
|
|
162
162
|
}
|
|
163
163
|
declare function useChangePassword(opts?: UseChangePasswordOptions): UseChangePasswordReturn;
|
|
164
164
|
|
|
165
|
+
interface UseGoogleLoginOptions {
|
|
166
|
+
onError?: (error: AuthError | Error) => void;
|
|
167
|
+
}
|
|
168
|
+
interface UseGoogleLoginReturn {
|
|
169
|
+
loginWithGoogle: (options?: OAuthLoginOptions) => void;
|
|
170
|
+
linkGoogle: (options?: OAuthLoginOptions) => Promise<void>;
|
|
171
|
+
isRedirecting: boolean;
|
|
172
|
+
error: AuthError | Error | null;
|
|
173
|
+
}
|
|
174
|
+
declare function useGoogleLogin(options?: UseGoogleLoginOptions): UseGoogleLoginReturn;
|
|
175
|
+
|
|
176
|
+
interface UseOAuthCallbackOptions {
|
|
177
|
+
onSuccess?: (user: AuthUser) => void;
|
|
178
|
+
onError?: (error: AuthError | Error) => void;
|
|
179
|
+
}
|
|
180
|
+
declare function useOAuthCallback(options?: UseOAuthCallbackOptions): {
|
|
181
|
+
complete: () => Promise<AuthUser>;
|
|
182
|
+
isLoading: boolean;
|
|
183
|
+
error: AuthError | Error;
|
|
184
|
+
};
|
|
185
|
+
|
|
165
186
|
/**
|
|
166
187
|
* Subscribe to a specific auth event. Cleans up on unmount.
|
|
167
188
|
* Uses a stable ref for the handler to avoid re-subscribing on every render.
|
|
@@ -537,4 +558,22 @@ interface RedirectToLoginProps {
|
|
|
537
558
|
*/
|
|
538
559
|
declare function RedirectToLogin({ to, preserveFrom }: RedirectToLoginProps): any;
|
|
539
560
|
|
|
540
|
-
|
|
561
|
+
interface GoogleLoginButtonProps extends OAuthLoginOptions {
|
|
562
|
+
children: ReactNode;
|
|
563
|
+
onError?: (error: Error) => void;
|
|
564
|
+
}
|
|
565
|
+
declare function GoogleLoginButton({ children, returnTo, onError }: GoogleLoginButtonProps): ReactElement<{
|
|
566
|
+
onClick?: (event: unknown) => void;
|
|
567
|
+
disabled?: boolean;
|
|
568
|
+
}, string | react.JSXElementConstructor<any>>;
|
|
569
|
+
|
|
570
|
+
interface OAuthCallbackProps {
|
|
571
|
+
fallback?: ReactNode;
|
|
572
|
+
errorFallback?: ReactNode | ((props: {
|
|
573
|
+
error: Error;
|
|
574
|
+
}) => ReactNode);
|
|
575
|
+
defaultRedirect?: string;
|
|
576
|
+
}
|
|
577
|
+
declare function OAuthCallback({ fallback, errorFallback, defaultRedirect, }: OAuthCallbackProps): react_jsx_runtime.JSX.Element;
|
|
578
|
+
|
|
579
|
+
export { AuthBoundary, type AuthEventEntry, AuthGate, AuthLoading, AuthProvider, Can, GoogleLoginButton, IfAuth, LoginButton, OAuthCallback, PermissionList, Protected, RedirectToLogin, Role, type SessionStatus, SignOutButton, SignedIn, SignedOut, UserAvatar, UserEmail, UserName, UserRole, useAuth, useAuthClient, useAuthEvent, useAuthEvents, useChangePassword, useForgotPassword, useGoogleLogin, useLogin, useLogout, useOAuthCallback, usePermissions, useRegister, useResetPassword, useSession, useUser };
|
|
@@ -310,11 +310,74 @@ function useChangePassword(opts) {
|
|
|
310
310
|
}
|
|
311
311
|
__name(useChangePassword, "useChangePassword");
|
|
312
312
|
|
|
313
|
+
// src/client/react/useGoogleLogin.ts
|
|
314
|
+
import { useCallback as useCallback7, useState as useState8 } from "react";
|
|
315
|
+
function useGoogleLogin(options) {
|
|
316
|
+
const client = useAuthClient();
|
|
317
|
+
const [isRedirecting, setIsRedirecting] = useState8(false);
|
|
318
|
+
const [error, setError] = useState8(null);
|
|
319
|
+
const fail = useCallback7((value) => {
|
|
320
|
+
const next = value instanceof Error ? value : new Error(String(value));
|
|
321
|
+
setIsRedirecting(false);
|
|
322
|
+
setError(next);
|
|
323
|
+
options?.onError?.(next);
|
|
324
|
+
}, [options?.onError]);
|
|
325
|
+
const loginWithGoogle = useCallback7((loginOptions) => {
|
|
326
|
+
setError(null);
|
|
327
|
+
setIsRedirecting(true);
|
|
328
|
+
try {
|
|
329
|
+
client.loginWithGoogle(loginOptions);
|
|
330
|
+
} catch (value) {
|
|
331
|
+
fail(value);
|
|
332
|
+
}
|
|
333
|
+
}, [client, fail]);
|
|
334
|
+
const linkGoogle = useCallback7(async (loginOptions) => {
|
|
335
|
+
setError(null);
|
|
336
|
+
setIsRedirecting(true);
|
|
337
|
+
try {
|
|
338
|
+
await client.linkOAuthAccount("google", loginOptions);
|
|
339
|
+
} catch (value) {
|
|
340
|
+
fail(value);
|
|
341
|
+
}
|
|
342
|
+
}, [client, fail]);
|
|
343
|
+
return { loginWithGoogle, linkGoogle, isRedirecting, error };
|
|
344
|
+
}
|
|
345
|
+
__name(useGoogleLogin, "useGoogleLogin");
|
|
346
|
+
|
|
347
|
+
// src/client/react/useOAuthCallback.ts
|
|
348
|
+
import { useCallback as useCallback8, useRef as useRef3, useState as useState9 } from "react";
|
|
349
|
+
function useOAuthCallback(options) {
|
|
350
|
+
const client = useAuthClient();
|
|
351
|
+
const promise = useRef3(null);
|
|
352
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
353
|
+
const [error, setError] = useState9(null);
|
|
354
|
+
const complete = useCallback8(async () => {
|
|
355
|
+
if (promise.current) return promise.current;
|
|
356
|
+
setIsLoading(true);
|
|
357
|
+
setError(null);
|
|
358
|
+
promise.current = client.completeOAuthLogin();
|
|
359
|
+
try {
|
|
360
|
+
const user = await promise.current;
|
|
361
|
+
options?.onSuccess?.(user);
|
|
362
|
+
return user;
|
|
363
|
+
} catch (value) {
|
|
364
|
+
const next = value instanceof Error ? value : new Error(String(value));
|
|
365
|
+
setError(next);
|
|
366
|
+
options?.onError?.(next);
|
|
367
|
+
throw next;
|
|
368
|
+
} finally {
|
|
369
|
+
setIsLoading(false);
|
|
370
|
+
}
|
|
371
|
+
}, [client, options?.onSuccess, options?.onError]);
|
|
372
|
+
return { complete, isLoading, error };
|
|
373
|
+
}
|
|
374
|
+
__name(useOAuthCallback, "useOAuthCallback");
|
|
375
|
+
|
|
313
376
|
// src/client/react/useAuthEvent.ts
|
|
314
|
-
import { useEffect as useEffect3, useRef as
|
|
377
|
+
import { useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
315
378
|
function useAuthEvent(event, handler) {
|
|
316
379
|
const client = useAuthClient();
|
|
317
|
-
const handlerRef =
|
|
380
|
+
const handlerRef = useRef4(handler);
|
|
318
381
|
handlerRef.current = handler;
|
|
319
382
|
useEffect3(() => {
|
|
320
383
|
const listener = /* @__PURE__ */ __name((data) => handlerRef.current(data), "listener");
|
|
@@ -325,7 +388,7 @@ function useAuthEvent(event, handler) {
|
|
|
325
388
|
__name(useAuthEvent, "useAuthEvent");
|
|
326
389
|
|
|
327
390
|
// src/client/react/useAuthEvents.ts
|
|
328
|
-
import { useEffect as useEffect4, useRef as
|
|
391
|
+
import { useEffect as useEffect4, useRef as useRef5, useState as useState10 } from "react";
|
|
329
392
|
var ALL_EVENTS = [
|
|
330
393
|
"login",
|
|
331
394
|
"logout",
|
|
@@ -338,8 +401,8 @@ var ALL_EVENTS = [
|
|
|
338
401
|
function useAuthEvents(opts) {
|
|
339
402
|
const client = useAuthClient();
|
|
340
403
|
const max = opts?.maxEntries ?? 100;
|
|
341
|
-
const [entries, setEntries] =
|
|
342
|
-
const maxRef =
|
|
404
|
+
const [entries, setEntries] = useState10([]);
|
|
405
|
+
const maxRef = useRef5(max);
|
|
343
406
|
maxRef.current = max;
|
|
344
407
|
useEffect4(() => {
|
|
345
408
|
const cleanups = [];
|
|
@@ -619,14 +682,73 @@ function RedirectToLogin({ to = "/login", preserveFrom = true }) {
|
|
|
619
682
|
return null;
|
|
620
683
|
}
|
|
621
684
|
__name(RedirectToLogin, "RedirectToLogin");
|
|
685
|
+
|
|
686
|
+
// src/client/react/GoogleLoginButton.tsx
|
|
687
|
+
import { Children as Children3, cloneElement as cloneElement3, isValidElement as isValidElement3 } from "react";
|
|
688
|
+
function GoogleLoginButton({ children, returnTo, onError }) {
|
|
689
|
+
const { loginWithGoogle, isRedirecting } = useGoogleLogin({ onError });
|
|
690
|
+
const child = Children3.only(children);
|
|
691
|
+
if (!isValidElement3(child)) {
|
|
692
|
+
throw new Error("<GoogleLoginButton> expects a single React element as its child");
|
|
693
|
+
}
|
|
694
|
+
const element = child;
|
|
695
|
+
return cloneElement3(element, {
|
|
696
|
+
onClick: /* @__PURE__ */ __name((event) => {
|
|
697
|
+
element.props.onClick?.(event);
|
|
698
|
+
if (!event?.defaultPrevented) {
|
|
699
|
+
loginWithGoogle({ returnTo });
|
|
700
|
+
}
|
|
701
|
+
}, "onClick"),
|
|
702
|
+
disabled: Boolean(element.props.disabled || isRedirecting)
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
__name(GoogleLoginButton, "GoogleLoginButton");
|
|
706
|
+
|
|
707
|
+
// src/client/react/OAuthCallback.tsx
|
|
708
|
+
import { useEffect as useEffect7 } from "react";
|
|
709
|
+
import { Fragment as Fragment14, jsx as jsx16 } from "react/jsx-runtime";
|
|
710
|
+
var safeReturnTo = /* @__PURE__ */ __name((value, fallback) => {
|
|
711
|
+
const safeFallback = fallback.startsWith("/") && !fallback.startsWith("//") && !fallback.includes("\\") ? fallback : "/";
|
|
712
|
+
if (!value || !value.startsWith("/") || value.startsWith("//") || value.includes("\\")) return safeFallback;
|
|
713
|
+
try {
|
|
714
|
+
const base = new URL("https://najm.invalid");
|
|
715
|
+
const parsed = new URL(value, base);
|
|
716
|
+
if (parsed.origin !== base.origin) return safeFallback;
|
|
717
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
718
|
+
} catch {
|
|
719
|
+
return safeFallback;
|
|
720
|
+
}
|
|
721
|
+
}, "safeReturnTo");
|
|
722
|
+
function OAuthCallback({
|
|
723
|
+
fallback = null,
|
|
724
|
+
errorFallback = null,
|
|
725
|
+
defaultRedirect = "/"
|
|
726
|
+
}) {
|
|
727
|
+
const { complete, error } = useOAuthCallback();
|
|
728
|
+
useEffect7(() => {
|
|
729
|
+
complete().then(() => {
|
|
730
|
+
if (typeof window === "undefined") return;
|
|
731
|
+
const params = new URLSearchParams(window.location.search);
|
|
732
|
+
window.location.replace(safeReturnTo(params.get("returnTo"), defaultRedirect));
|
|
733
|
+
}).catch(() => {
|
|
734
|
+
});
|
|
735
|
+
}, [complete, defaultRedirect]);
|
|
736
|
+
if (error) {
|
|
737
|
+
return /* @__PURE__ */ jsx16(Fragment14, { children: typeof errorFallback === "function" ? errorFallback({ error }) : errorFallback });
|
|
738
|
+
}
|
|
739
|
+
return /* @__PURE__ */ jsx16(Fragment14, { children: fallback });
|
|
740
|
+
}
|
|
741
|
+
__name(OAuthCallback, "OAuthCallback");
|
|
622
742
|
export {
|
|
623
743
|
AuthBoundary,
|
|
624
744
|
AuthGate,
|
|
625
745
|
AuthLoading,
|
|
626
746
|
AuthProvider,
|
|
627
747
|
Can,
|
|
748
|
+
GoogleLoginButton,
|
|
628
749
|
IfAuth,
|
|
629
750
|
LoginButton,
|
|
751
|
+
OAuthCallback,
|
|
630
752
|
PermissionList,
|
|
631
753
|
Protected,
|
|
632
754
|
RedirectToLogin,
|
|
@@ -644,8 +766,10 @@ export {
|
|
|
644
766
|
useAuthEvents,
|
|
645
767
|
useChangePassword,
|
|
646
768
|
useForgotPassword,
|
|
769
|
+
useGoogleLogin,
|
|
647
770
|
useLogin,
|
|
648
771
|
useLogout,
|
|
772
|
+
useOAuthCallback,
|
|
649
773
|
usePermissions,
|
|
650
774
|
useRegister,
|
|
651
775
|
useResetPassword,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as AuthUser, F as FetchClient, R as RetryConfig, N as NajmAuthClient } from '../../NajmAuthClient-
|
|
1
|
+
import { e as AuthUser, F as FetchClient, R as RetryConfig, N as NajmAuthClient } from '../../NajmAuthClient-B9dGk9MH.js';
|
|
2
2
|
export { withAuthMiddleware } from '../edge.js';
|
|
3
3
|
import 'next/server';
|
|
4
4
|
|
|
@@ -588,6 +588,43 @@ var NajmAuthClient = class _NajmAuthClient {
|
|
|
588
588
|
);
|
|
589
589
|
return res.data;
|
|
590
590
|
}
|
|
591
|
+
getOAuthLoginUrl(provider, options = {}) {
|
|
592
|
+
const baseURL = this.config.baseURL.replace(/\/$/, "");
|
|
593
|
+
const authPrefix = this.prefix.startsWith("/") ? this.prefix : `/${this.prefix}`;
|
|
594
|
+
const raw = `${baseURL}${authPrefix}/oauth/${provider}/start`;
|
|
595
|
+
const absolute = /^[a-z][a-z\d+.-]*:\/\//i.test(raw);
|
|
596
|
+
const url = new URL(raw, absolute ? void 0 : "https://najm.invalid");
|
|
597
|
+
if (options.returnTo) {
|
|
598
|
+
url.searchParams.set("returnTo", this.validateReturnTo(options.returnTo));
|
|
599
|
+
}
|
|
600
|
+
return absolute ? url.toString() : `${url.pathname}${url.search}`;
|
|
601
|
+
}
|
|
602
|
+
loginWithOAuth(provider, options) {
|
|
603
|
+
if (typeof window === "undefined") {
|
|
604
|
+
throw new Error("OAuth login requires a browser environment");
|
|
605
|
+
}
|
|
606
|
+
window.location.assign(this.getOAuthLoginUrl(provider, options));
|
|
607
|
+
}
|
|
608
|
+
loginWithGoogle(options) {
|
|
609
|
+
this.loginWithOAuth("google", options);
|
|
610
|
+
}
|
|
611
|
+
async linkOAuthAccount(provider, options = {}) {
|
|
612
|
+
const query = options.returnTo ? `?${new URLSearchParams({ returnTo: this.validateReturnTo(options.returnTo) })}` : "";
|
|
613
|
+
const res = await this.api.post(
|
|
614
|
+
`${this.prefix}/oauth/${provider}/link${query}`
|
|
615
|
+
);
|
|
616
|
+
if (!res.data?.authorizationUrl) throw new Error("OAuth provider did not return an authorization URL");
|
|
617
|
+
if (typeof window === "undefined") throw new Error("OAuth linking requires a browser environment");
|
|
618
|
+
window.location.assign(res.data.authorizationUrl);
|
|
619
|
+
}
|
|
620
|
+
async completeOAuthLogin() {
|
|
621
|
+
await this.refresh();
|
|
622
|
+
const user = await this.fetchUser();
|
|
623
|
+
if (!user) throw new Error("OAuth session could not be completed");
|
|
624
|
+
this.tabSync?.broadcastSync(this.getSyncPayload());
|
|
625
|
+
this.emit("login", user);
|
|
626
|
+
return user;
|
|
627
|
+
}
|
|
591
628
|
async logout() {
|
|
592
629
|
this.resetState();
|
|
593
630
|
this.tabSync?.broadcastLogout();
|
|
@@ -879,6 +916,18 @@ var NajmAuthClient = class _NajmAuthClient {
|
|
|
879
916
|
this.eventListeners.get("stateChange")?.forEach((h) => h(this.state));
|
|
880
917
|
}
|
|
881
918
|
}
|
|
919
|
+
validateReturnTo(value) {
|
|
920
|
+
const candidate = value.trim();
|
|
921
|
+
if (!candidate.startsWith("/") || candidate.startsWith("//") || candidate.includes("\\")) {
|
|
922
|
+
throw new Error("returnTo must be a same-origin path");
|
|
923
|
+
}
|
|
924
|
+
const base = new URL("https://najm.invalid");
|
|
925
|
+
const parsed = new URL(candidate, base);
|
|
926
|
+
if (parsed.origin !== base.origin || parsed.username || parsed.password) {
|
|
927
|
+
throw new Error("returnTo must be a same-origin path");
|
|
928
|
+
}
|
|
929
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
930
|
+
}
|
|
882
931
|
};
|
|
883
932
|
function createAuthClient(config) {
|
|
884
933
|
return new NajmAuthClient(config);
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import * as najm_core from 'najm-core';
|
|
|
2
2
|
import { Container } from 'najm-core';
|
|
3
3
|
import { ValidationPluginConfig } from 'najm-validation';
|
|
4
4
|
import { RateLimitPluginConfig } from 'najm-rate';
|
|
5
|
+
import { EmailPluginConfig, EmailService } from 'najm-email';
|
|
5
6
|
import { I18nService } from 'najm-i18n';
|
|
6
|
-
import { EmailService } from 'najm-email';
|
|
7
7
|
import { TDb, SeedEntry } from 'najm-database';
|
|
8
8
|
import { User, NewUser, RoleEntity, NewRoleEntity, Permission, NewPermission, RolePermission } from './schema/pg.js';
|
|
9
|
-
export { NewRolePermission, NewToken, Token, authSchema, baseFields, permissionsTable, rolePermissionsTable, rolesTable, tokenStatusEnum, tokenTypeEnum, tokensTable, userStatusEnum, usersTable } from './schema/pg.js';
|
|
9
|
+
export { NewOAuthAccount, NewRolePermission, NewToken, OAuthAccount, Token, authSchema, baseFields, oauthAccountsTable, permissionsTable, rolePermissionsTable, rolesTable, tokenStatusEnum, tokenTypeEnum, tokensTable, userStatusEnum, usersTable } from './schema/pg.js';
|
|
10
10
|
import { CacheService } from 'najm-cache';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import { GuardResult } from 'najm-guard';
|
|
@@ -45,6 +45,48 @@ interface SessionCookieConfig {
|
|
|
45
45
|
/** Secret used to HMAC-sign the cookie. Defaults to jwt.accessSecret. */
|
|
46
46
|
secret?: string;
|
|
47
47
|
}
|
|
48
|
+
type OAuthProvider = 'google';
|
|
49
|
+
interface GoogleOAuthConfig {
|
|
50
|
+
/** Google OAuth web client ID. Falls back to GOOGLE_CLIENT_ID. */
|
|
51
|
+
clientId?: string;
|
|
52
|
+
/** Google OAuth web client secret. Falls back to GOOGLE_CLIENT_SECRET. */
|
|
53
|
+
clientSecret?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Absolute backend callback URL registered in Google Cloud. Falls back to
|
|
56
|
+
* GOOGLE_CALLBACK_URL, then `${frontendUrl}/api/auth/oauth/google/callback`.
|
|
57
|
+
*/
|
|
58
|
+
callbackUrl?: string;
|
|
59
|
+
/** Frontend route that completes the Najm client session. */
|
|
60
|
+
frontendCallbackPath?: string;
|
|
61
|
+
/** Frontend route that receives stable OAuth errors. */
|
|
62
|
+
errorRedirectPath?: string;
|
|
63
|
+
/** Create a Najm user for a new Google identity (default: true). */
|
|
64
|
+
allowSignup?: boolean;
|
|
65
|
+
/** Link an existing user by verified email (default: false). */
|
|
66
|
+
autoLinkVerifiedEmail?: boolean;
|
|
67
|
+
/** Optional Google Workspace hosted-domain allowlist. */
|
|
68
|
+
allowedHostedDomains?: string[];
|
|
69
|
+
}
|
|
70
|
+
interface OAuthConfig {
|
|
71
|
+
/**
|
|
72
|
+
* Enable Google with environment defaults (`google: true`), or override
|
|
73
|
+
* individual settings for split-origin deployments and policy changes.
|
|
74
|
+
*/
|
|
75
|
+
google?: true | GoogleOAuthConfig;
|
|
76
|
+
}
|
|
77
|
+
interface ResolvedGoogleOAuthConfig {
|
|
78
|
+
clientId: string;
|
|
79
|
+
clientSecret: string;
|
|
80
|
+
callbackUrl: string;
|
|
81
|
+
frontendCallbackPath: string;
|
|
82
|
+
errorRedirectPath: string;
|
|
83
|
+
allowSignup: boolean;
|
|
84
|
+
autoLinkVerifiedEmail: boolean;
|
|
85
|
+
allowedHostedDomains: string[];
|
|
86
|
+
}
|
|
87
|
+
interface ResolvedOAuthConfig {
|
|
88
|
+
google?: ResolvedGoogleOAuthConfig;
|
|
89
|
+
}
|
|
48
90
|
/**
|
|
49
91
|
* Complete auth plugin configuration (internal)
|
|
50
92
|
*/
|
|
@@ -73,6 +115,8 @@ interface AuthConfig {
|
|
|
73
115
|
bcryptRounds: number;
|
|
74
116
|
/** Session cookie cache settings */
|
|
75
117
|
session: SessionCookieConfig;
|
|
118
|
+
/** Resolved external identity-provider configuration. */
|
|
119
|
+
oauth?: ResolvedOAuthConfig;
|
|
76
120
|
}
|
|
77
121
|
/**
|
|
78
122
|
* Auth plugin configuration options
|
|
@@ -88,6 +132,8 @@ interface AuthSchema {
|
|
|
88
132
|
roles: any;
|
|
89
133
|
permissions: any;
|
|
90
134
|
rolePermissions: any;
|
|
135
|
+
/** Required when an OAuth provider is enabled. */
|
|
136
|
+
oauthAccounts?: any;
|
|
91
137
|
}
|
|
92
138
|
type AuthPluginConfig = {
|
|
93
139
|
/**
|
|
@@ -130,8 +176,12 @@ type AuthPluginConfig = {
|
|
|
130
176
|
validation?: ValidationPluginConfig;
|
|
131
177
|
/** Optional config forwarded to rateLimit() dependency */
|
|
132
178
|
rateLimit?: RateLimitPluginConfig;
|
|
179
|
+
/** Email transport used by password reset and verification flows. */
|
|
180
|
+
email?: EmailPluginConfig;
|
|
133
181
|
/** AES-256-GCM key for reversible encryption (e.g. API keys). Falls back to NAJM_ENCRYPTION_KEY env var. */
|
|
134
182
|
encryptionKey?: string;
|
|
183
|
+
/** External identity providers. */
|
|
184
|
+
oauth?: OAuthConfig;
|
|
135
185
|
};
|
|
136
186
|
/**
|
|
137
187
|
* JWT payload structure
|
|
@@ -208,7 +258,17 @@ var auth = {
|
|
|
208
258
|
sessionExpired: "Session has expired",
|
|
209
259
|
accountLocked: "Account is temporarily locked. Please try again later.",
|
|
210
260
|
accountInactive: "Account is inactive. Please contact support.",
|
|
211
|
-
emailNotVerified: "Please verify your email address before signing in."
|
|
261
|
+
emailNotVerified: "Please verify your email address before signing in.",
|
|
262
|
+
oauthProviderDisabled: "Google sign-in is not configured.",
|
|
263
|
+
oauthStateInvalid: "The Google sign-in attempt is invalid or expired.",
|
|
264
|
+
oauthAccessDenied: "Google sign-in was cancelled.",
|
|
265
|
+
oauthProviderError: "Google sign-in could not be completed.",
|
|
266
|
+
oauthVerifiedEmailRequired: "Google must provide a verified email address.",
|
|
267
|
+
oauthAccountLinkRequired: "Sign in with your password and link Google from your account.",
|
|
268
|
+
oauthProviderAccountLinked: "This Google account is already linked.",
|
|
269
|
+
oauthSignupDisabled: "Registration with Google is disabled.",
|
|
270
|
+
oauthHostedDomainDenied: "This Google Workspace domain is not allowed.",
|
|
271
|
+
oauthLinkSessionExpired: "Your session changed before Google could be linked. Please try again."
|
|
212
272
|
},
|
|
213
273
|
success: {
|
|
214
274
|
login: "Login successful",
|
|
@@ -218,7 +278,9 @@ var auth = {
|
|
|
218
278
|
passwordResetSent: "If that email exists, a reset link has been sent",
|
|
219
279
|
passwordReset: "Password has been reset successfully",
|
|
220
280
|
accountInviteSent: "Invitation sent successfully",
|
|
221
|
-
tokenRefreshed: "Token refreshed successfully"
|
|
281
|
+
tokenRefreshed: "Token refreshed successfully",
|
|
282
|
+
oauthLogin: "Google sign-in successful",
|
|
283
|
+
oauthLinked: "Google account linked successfully"
|
|
222
284
|
},
|
|
223
285
|
emails: {
|
|
224
286
|
passwordReset: {
|
|
@@ -314,6 +376,16 @@ declare const AUTH_LOCALES: {
|
|
|
314
376
|
accountLocked: string;
|
|
315
377
|
accountInactive: string;
|
|
316
378
|
emailNotVerified: string;
|
|
379
|
+
oauthProviderDisabled: string;
|
|
380
|
+
oauthStateInvalid: string;
|
|
381
|
+
oauthAccessDenied: string;
|
|
382
|
+
oauthProviderError: string;
|
|
383
|
+
oauthVerifiedEmailRequired: string;
|
|
384
|
+
oauthAccountLinkRequired: string;
|
|
385
|
+
oauthProviderAccountLinked: string;
|
|
386
|
+
oauthSignupDisabled: string;
|
|
387
|
+
oauthHostedDomainDenied: string;
|
|
388
|
+
oauthLinkSessionExpired: string;
|
|
317
389
|
};
|
|
318
390
|
success: {
|
|
319
391
|
login: string;
|
|
@@ -324,6 +396,8 @@ declare const AUTH_LOCALES: {
|
|
|
324
396
|
passwordReset: string;
|
|
325
397
|
accountInviteSent: string;
|
|
326
398
|
tokenRefreshed: string;
|
|
399
|
+
oauthLogin: string;
|
|
400
|
+
oauthLinked: string;
|
|
327
401
|
};
|
|
328
402
|
emails: {
|
|
329
403
|
passwordReset: {
|
|
@@ -478,6 +552,9 @@ declare class UserRepository {
|
|
|
478
552
|
getByEmail(email: string): Promise<(User & {
|
|
479
553
|
role?: string | null;
|
|
480
554
|
}) | undefined>;
|
|
555
|
+
getByEmailInsensitive(email: string): Promise<(User & {
|
|
556
|
+
role?: string | null;
|
|
557
|
+
}) | undefined>;
|
|
481
558
|
create(data: NewUser): Promise<User>;
|
|
482
559
|
update(id: string, data: Partial<NewUser>): Promise<User | undefined>;
|
|
483
560
|
updateLastLogin(id: string): Promise<User>;
|
|
@@ -737,6 +814,9 @@ declare class UserService {
|
|
|
737
814
|
findByEmail(email: string): Promise<(User & {
|
|
738
815
|
role?: string | null;
|
|
739
816
|
}) | undefined>;
|
|
817
|
+
findByEmailInsensitive(email: string): Promise<(User & {
|
|
818
|
+
role?: string | null;
|
|
819
|
+
}) | undefined>;
|
|
740
820
|
getAuthRecordById(id: string): Promise<User | undefined>;
|
|
741
821
|
create(data: Record<string, any>): Promise<SanitizedUser>;
|
|
742
822
|
update(id: string, data: Record<string, any>): Promise<SanitizedUser>;
|
|
@@ -1093,6 +1173,16 @@ type UserIdInParam = z.infer<typeof userIdInParam>;
|
|
|
1093
1173
|
type AssignRoleParams = z.infer<typeof assignRoleParams>;
|
|
1094
1174
|
type UserListQuery = z.infer<typeof userListQuery>;
|
|
1095
1175
|
|
|
1176
|
+
declare class AuthSessionService {
|
|
1177
|
+
private tokenService;
|
|
1178
|
+
private userService;
|
|
1179
|
+
private cookieManager;
|
|
1180
|
+
constructor(tokenService: TokenService, userService: UserService, cookieManager: CookieManager);
|
|
1181
|
+
establish(user: SanitizedUser): Promise<TokenPair & {
|
|
1182
|
+
user: SanitizedUser;
|
|
1183
|
+
}>;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1096
1186
|
/**
|
|
1097
1187
|
* Identity fields for creating a user behind a person record (parent, student,
|
|
1098
1188
|
* teacher, staff…). Role can be given by name (`role`) or id (`roleId`).
|
|
@@ -1114,11 +1204,12 @@ declare class AuthService {
|
|
|
1114
1204
|
private cookieManager;
|
|
1115
1205
|
private i18nService;
|
|
1116
1206
|
private emailService;
|
|
1207
|
+
private authSessionService?;
|
|
1117
1208
|
private config;
|
|
1118
1209
|
private t;
|
|
1119
1210
|
private logger;
|
|
1120
1211
|
private dummyHash?;
|
|
1121
|
-
constructor(tokenService: TokenService, userService: UserService, userValidator: UserValidator, encryptionService: EncryptionService, cookieManager: CookieManager, i18nService: I18nService, emailService: EmailService);
|
|
1212
|
+
constructor(tokenService: TokenService, userService: UserService, userValidator: UserValidator, encryptionService: EncryptionService, cookieManager: CookieManager, i18nService: I18nService, emailService: EmailService, authSessionService?: AuthSessionService);
|
|
1122
1213
|
private isLockoutActive;
|
|
1123
1214
|
private nextLockoutUntil;
|
|
1124
1215
|
private getDummyHash;
|
|
@@ -1306,7 +1397,7 @@ interface RunAsUser {
|
|
|
1306
1397
|
}
|
|
1307
1398
|
declare function runAsUser<T>(container: Container, user: RunAsUser, fn: () => Promise<T> | T): Promise<T>;
|
|
1308
1399
|
|
|
1309
|
-
declare const AUTH_MODULE: readonly [typeof AuthService, typeof CookieManager, typeof EncryptionService, typeof AuthGuard, typeof AuthController, typeof AuthResolver];
|
|
1400
|
+
declare const AUTH_MODULE: readonly [typeof AuthService, typeof AuthSessionService, typeof CookieManager, typeof EncryptionService, typeof AuthGuard, typeof AuthController, typeof AuthResolver];
|
|
1310
1401
|
|
|
1311
1402
|
declare class PermissionRepository {
|
|
1312
1403
|
db: TDb;
|
|
@@ -2197,4 +2288,4 @@ declare const authSeed: (config: AuthSeedConfig) => Record<string, SeedEntry>;
|
|
|
2197
2288
|
*/
|
|
2198
2289
|
declare function seedAuthData(config: SeedAuthDataConfig): Promise<SeedAuthDataResult>;
|
|
2199
2290
|
|
|
2200
|
-
export { AUTH_CONFIG, en as AUTH_EN, AUTH_LOCALES, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthPluginConfig, AuthQueries, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, type AuthUser, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type DefineRolesOptions, type EmailParam, EncryptionService, type InviteUserDto, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, NewPermission, NewRoleEntity, NewUser, Owned, type OwnedMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, type ProvisionUserInput, ROLES, ROLE_GROUPS, type RefreshTokenDto, type RegisterDto, type ResetPasswordDto, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type RunAsUser, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, TOKEN_STATUS, TOKEN_TYPE, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, type UserListQuery, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createPermissionDto, createRoleDto, createTokenDto, createUserDto, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, inviteUserDto, isAdmin, isAdministrator, isAuth, isEmpty, isFile, isPath, join, languageParam, loginDto, own, parseSchema, permissionIdParam, pickProps, refreshTokenDto, registerDto, resetPasswordDto, revokeTokenDto, roleIdParam, runAsUser, seedAuthData, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, userListQuery, verifyTokenDto, where };
|
|
2291
|
+
export { AUTH_CONFIG, en as AUTH_EN, AUTH_LOCALES, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthPluginConfig, AuthQueries, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, AuthSessionService, type AuthUser, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type DefineRolesOptions, type EmailParam, EncryptionService, type GoogleOAuthConfig, type InviteUserDto, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, NewPermission, NewRoleEntity, NewUser, type OAuthConfig, type OAuthProvider, Owned, type OwnedMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, type ProvisionUserInput, ROLES, ROLE_GROUPS, type RefreshTokenDto, type RegisterDto, type ResetPasswordDto, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type RunAsUser, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, TOKEN_STATUS, TOKEN_TYPE, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, type UserListQuery, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createPermissionDto, createRoleDto, createTokenDto, createUserDto, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, inviteUserDto, isAdmin, isAdministrator, isAuth, isEmpty, isFile, isPath, join, languageParam, loginDto, own, parseSchema, permissionIdParam, pickProps, refreshTokenDto, registerDto, resetPasswordDto, revokeTokenDto, roleIdParam, runAsUser, seedAuthData, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, userListQuery, verifyTokenDto, where };
|