@prsm/auth 1.0.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 +226 -0
- package/index.d.ts +19 -0
- package/package.json +76 -0
- package/src/__tests__/auth.test.js +1171 -0
- package/src/__tests__/impersonation-test-setup.js +208 -0
- package/src/__tests__/impersonation.test.js +473 -0
- package/src/__tests__/oauth-test-setup.js +136 -0
- package/src/__tests__/oauth.test.js +400 -0
- package/src/__tests__/prsm.test.js +215 -0
- package/src/__tests__/test-setup.js +385 -0
- package/src/__tests__/totp.test.js +158 -0
- package/src/__tests__/two-factor-test-setup.js +331 -0
- package/src/__tests__/two-factor.test.js +396 -0
- package/src/activity-logger.js +228 -0
- package/src/auth-context.js +120 -0
- package/src/auth-functions.js +520 -0
- package/src/auth-manager.js +1371 -0
- package/src/errors.js +173 -0
- package/src/hooks.js +41 -0
- package/src/index.js +23 -0
- package/src/invalidation.js +166 -0
- package/src/middleware.js +33 -0
- package/src/providers/azure-provider.js +114 -0
- package/src/providers/base-provider.js +152 -0
- package/src/providers/github-provider.js +86 -0
- package/src/providers/google-provider.js +76 -0
- package/src/providers/index.js +4 -0
- package/src/queries.js +543 -0
- package/src/schema.js +261 -0
- package/src/totp.js +221 -0
- package/src/two-factor/index.js +3 -0
- package/src/two-factor/otp-provider.js +128 -0
- package/src/two-factor/totp-provider.js +98 -0
- package/src/two-factor/two-factor-manager.js +676 -0
- package/src/types.js +399 -0
- package/src/user-roles.js +128 -0
- package/src/util.js +32 -0
- package/types/activity-logger.d.ts +73 -0
- package/types/auth-context.d.ts +88 -0
- package/types/auth-functions.d.ts +151 -0
- package/types/auth-manager.d.ts +365 -0
- package/types/errors.d.ts +108 -0
- package/types/hooks.d.ts +30 -0
- package/types/index.d.ts +13 -0
- package/types/invalidation.d.ts +40 -0
- package/types/middleware.d.ts +11 -0
- package/types/providers/azure-provider.d.ts +35 -0
- package/types/providers/base-provider.d.ts +52 -0
- package/types/providers/github-provider.d.ts +29 -0
- package/types/providers/google-provider.d.ts +29 -0
- package/types/providers/index.d.ts +4 -0
- package/types/queries.d.ts +287 -0
- package/types/schema.d.ts +37 -0
- package/types/totp.d.ts +72 -0
- package/types/two-factor/index.d.ts +3 -0
- package/types/two-factor/otp-provider.d.ts +57 -0
- package/types/two-factor/totp-provider.d.ts +58 -0
- package/types/two-factor/two-factor-manager.d.ts +191 -0
- package/types/types.d.ts +688 -0
- package/types/user-roles.d.ts +47 -0
- package/types/util.d.ts +3 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export class AuthError extends Error {
|
|
2
|
+
/** @param {string} message */
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export class ConfirmationExpiredError extends AuthError {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
export class ConfirmationNotFoundError extends AuthError {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
export class EmailNotVerifiedError extends AuthError {
|
|
12
|
+
constructor();
|
|
13
|
+
}
|
|
14
|
+
export class EmailTakenError extends AuthError {
|
|
15
|
+
constructor();
|
|
16
|
+
}
|
|
17
|
+
export class InvalidEmailError extends AuthError {
|
|
18
|
+
constructor();
|
|
19
|
+
}
|
|
20
|
+
export class InvalidPasswordError extends AuthError {
|
|
21
|
+
constructor();
|
|
22
|
+
}
|
|
23
|
+
export class InvalidTokenError extends AuthError {
|
|
24
|
+
constructor();
|
|
25
|
+
}
|
|
26
|
+
export class ResetDisabledError extends AuthError {
|
|
27
|
+
constructor();
|
|
28
|
+
}
|
|
29
|
+
export class ResetExpiredError extends AuthError {
|
|
30
|
+
constructor();
|
|
31
|
+
}
|
|
32
|
+
export class ResetNotFoundError extends AuthError {
|
|
33
|
+
constructor();
|
|
34
|
+
}
|
|
35
|
+
export class TooManyResetsError extends AuthError {
|
|
36
|
+
constructor();
|
|
37
|
+
}
|
|
38
|
+
export class UserInactiveError extends AuthError {
|
|
39
|
+
constructor();
|
|
40
|
+
}
|
|
41
|
+
export class UserNotFoundError extends AuthError {
|
|
42
|
+
constructor();
|
|
43
|
+
}
|
|
44
|
+
export class UserNotLoggedInError extends AuthError {
|
|
45
|
+
constructor();
|
|
46
|
+
}
|
|
47
|
+
export class RateLimitedError extends AuthError {
|
|
48
|
+
/** @param {number} [retryAfter] milliseconds until the next attempt is allowed */
|
|
49
|
+
constructor(retryAfter?: number);
|
|
50
|
+
retryAfter: number;
|
|
51
|
+
}
|
|
52
|
+
export class SecondFactorRequiredError extends AuthError {
|
|
53
|
+
/**
|
|
54
|
+
* @param {{ totp?: boolean, email?: { otpValue: string, maskedContact: string }, sms?: { otpValue: string, maskedContact: string } }} availableMethods
|
|
55
|
+
*/
|
|
56
|
+
constructor(availableMethods: {
|
|
57
|
+
totp?: boolean;
|
|
58
|
+
email?: {
|
|
59
|
+
otpValue: string;
|
|
60
|
+
maskedContact: string;
|
|
61
|
+
};
|
|
62
|
+
sms?: {
|
|
63
|
+
otpValue: string;
|
|
64
|
+
maskedContact: string;
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
availableMethods: {
|
|
68
|
+
totp?: boolean;
|
|
69
|
+
email?: {
|
|
70
|
+
otpValue: string;
|
|
71
|
+
maskedContact: string;
|
|
72
|
+
};
|
|
73
|
+
sms?: {
|
|
74
|
+
otpValue: string;
|
|
75
|
+
maskedContact: string;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export class InvalidTwoFactorCodeError extends AuthError {
|
|
80
|
+
constructor();
|
|
81
|
+
}
|
|
82
|
+
export class TwoFactorExpiredError extends AuthError {
|
|
83
|
+
constructor();
|
|
84
|
+
}
|
|
85
|
+
export class TwoFactorNotSetupError extends AuthError {
|
|
86
|
+
constructor();
|
|
87
|
+
}
|
|
88
|
+
export class TwoFactorAlreadyEnabledError extends AuthError {
|
|
89
|
+
constructor();
|
|
90
|
+
}
|
|
91
|
+
export class InvalidBackupCodeError extends AuthError {
|
|
92
|
+
constructor();
|
|
93
|
+
}
|
|
94
|
+
export class TwoFactorSetupIncompleteError extends AuthError {
|
|
95
|
+
constructor();
|
|
96
|
+
}
|
|
97
|
+
export class ImpersonationDisabledError extends AuthError {
|
|
98
|
+
constructor();
|
|
99
|
+
}
|
|
100
|
+
export class ImpersonationNotAllowedError extends AuthError {
|
|
101
|
+
constructor();
|
|
102
|
+
}
|
|
103
|
+
export class AlreadyImpersonatingError extends AuthError {
|
|
104
|
+
constructor();
|
|
105
|
+
}
|
|
106
|
+
export class NotImpersonatingError extends AuthError {
|
|
107
|
+
constructor();
|
|
108
|
+
}
|
package/types/hooks.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./types.js").Tracer} Tracer
|
|
3
|
+
* @typedef {import("./types.js").Limiter} Limiter
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Run fn inside a tracing span when a tracer is provided, otherwise run it plain.
|
|
7
|
+
* Matches the @prsm/trace tracer shape: tracer.span(name, attributes, fn).
|
|
8
|
+
* @template T
|
|
9
|
+
* @param {Tracer | undefined} tracer
|
|
10
|
+
* @param {string} name
|
|
11
|
+
* @param {Record<string, any>} attributes
|
|
12
|
+
* @param {() => Promise<T>} fn
|
|
13
|
+
* @returns {Promise<T>}
|
|
14
|
+
*/
|
|
15
|
+
export function withSpan<T>(tracer: Tracer | undefined, name: string, attributes: Record<string, any>, fn: () => Promise<T>): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Consume one unit against a limiter for the given key. The @prsm/limit
|
|
18
|
+
* algorithms expose different verbs (tokenBucket.take, slidingWindow.hit,
|
|
19
|
+
* leakyBucket.drip); all return { allowed, retryAfter }. We accept any of them
|
|
20
|
+
* plus a generic consume/check so callers can pass a limiter instance directly.
|
|
21
|
+
* @param {Limiter | undefined} limiter
|
|
22
|
+
* @param {string} key
|
|
23
|
+
* @returns {Promise<{ allowed: boolean, retryAfter?: number } | null>}
|
|
24
|
+
*/
|
|
25
|
+
export function consumeLimit(limiter: Limiter | undefined, key: string): Promise<{
|
|
26
|
+
allowed: boolean;
|
|
27
|
+
retryAfter?: number;
|
|
28
|
+
} | null>;
|
|
29
|
+
export type Tracer = import("./types.js").Tracer;
|
|
30
|
+
export type Limiter = import("./types.js").Limiter;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { createAuthMiddleware } from "./middleware.js";
|
|
2
|
+
export { createAuthContext } from "./auth-context.js";
|
|
3
|
+
export * as authFunctions from "./auth-functions.js";
|
|
4
|
+
export * from "./auth-functions.js";
|
|
5
|
+
export * from "./types.js";
|
|
6
|
+
export * from "./errors.js";
|
|
7
|
+
export { ActivityLogger } from "./activity-logger.js";
|
|
8
|
+
export { closeInvalidationListeners } from "./invalidation.js";
|
|
9
|
+
export { createAuthTables, dropAuthTables, cleanupExpiredTokens, getAuthTableStats } from "./schema.js";
|
|
10
|
+
export { defineRoles, addRoleToUser, removeRoleFromUser, setUserRoles, getUserRoles } from "./user-roles.js";
|
|
11
|
+
export { isValidEmail, validateEmail } from "./util.js";
|
|
12
|
+
export { TwoFactorManager, TotpProvider, OtpProvider } from "./two-factor/index.js";
|
|
13
|
+
export { GitHubProvider, GoogleProvider, AzureProvider, BaseOAuthProvider } from "./providers/index.js";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Start the LISTEN connection for this config's pool/channel if it isn't already
|
|
3
|
+
* running. Idempotent and non-blocking - the first call kicks off the connection
|
|
4
|
+
* and returns; failures mark the listener broken so callers fall back to polling.
|
|
5
|
+
* @param {AuthConfig} config
|
|
6
|
+
*/
|
|
7
|
+
export function ensureListener(config: AuthConfig): void;
|
|
8
|
+
/**
|
|
9
|
+
* Broadcast that an account's auth state changed so other instances resync it
|
|
10
|
+
* immediately. No-op unless invalidation is enabled.
|
|
11
|
+
* @param {AuthConfig} config
|
|
12
|
+
* @param {number} accountId
|
|
13
|
+
* @returns {Promise<void>}
|
|
14
|
+
*/
|
|
15
|
+
export function notifyInvalidation(config: AuthConfig, accountId: number): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the given account was signaled invalid more recently than `sinceTs`.
|
|
18
|
+
* @param {AuthConfig} config
|
|
19
|
+
* @param {number} accountId
|
|
20
|
+
* @param {number} sinceTs epoch millis
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
export function wasInvalidatedSince(config: AuthConfig, accountId: number, sinceTs: number): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Release all listener connections. Intended for test teardown and graceful
|
|
26
|
+
* shutdown - production processes normally keep listeners for their lifetime.
|
|
27
|
+
* @returns {Promise<void>}
|
|
28
|
+
*/
|
|
29
|
+
export function closeInvalidationListeners(): Promise<void>;
|
|
30
|
+
export type AuthConfig = import("./types.js").AuthConfig;
|
|
31
|
+
export type ListenerState = {
|
|
32
|
+
channel: string;
|
|
33
|
+
/**
|
|
34
|
+
* accountId -> timestamp of last signal
|
|
35
|
+
*/
|
|
36
|
+
invalidated: Map<number, number>;
|
|
37
|
+
started: boolean;
|
|
38
|
+
broken: boolean;
|
|
39
|
+
client: import("pg").PoolClient | null;
|
|
40
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./types.js").AuthConfig} AuthConfig
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create the Express middleware that attaches an AuthManager to req.auth,
|
|
6
|
+
* resyncs the session, and processes any remember-me token.
|
|
7
|
+
* @param {AuthConfig} config
|
|
8
|
+
* @returns {import("express").RequestHandler}
|
|
9
|
+
*/
|
|
10
|
+
export function createAuthMiddleware(config: AuthConfig): import("express").RequestHandler;
|
|
11
|
+
export type AuthConfig = import("./types.js").AuthConfig;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../types.js").AuthConfig} AuthConfig
|
|
3
|
+
* @typedef {import("../types.js").OAuthUserData} OAuthUserData
|
|
4
|
+
* @typedef {import("../types.js").AzureProviderConfig} AzureProviderConfig
|
|
5
|
+
*/
|
|
6
|
+
export class AzureProvider extends BaseOAuthProvider {
|
|
7
|
+
/**
|
|
8
|
+
* @param {AzureProviderConfig} config
|
|
9
|
+
* @param {AuthConfig} authConfig
|
|
10
|
+
* @param {import("../auth-manager.js").AuthManager} authManager
|
|
11
|
+
*/
|
|
12
|
+
constructor(config: AzureProviderConfig, authConfig: AuthConfig, authManager: import("../auth-manager.js").AuthManager);
|
|
13
|
+
/**
|
|
14
|
+
* Build the Azure AD authorization URL.
|
|
15
|
+
* @param {string} [state]
|
|
16
|
+
* @param {string[]} [scopes]
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
getAuthUrl(state?: string, scopes?: string[]): string;
|
|
20
|
+
/**
|
|
21
|
+
* Exchange the callback code and resolve the Azure user profile.
|
|
22
|
+
* @param {import("express").Request} req
|
|
23
|
+
* @returns {Promise<OAuthUserData>}
|
|
24
|
+
* @throws {Error} when no code is provided or no email is found
|
|
25
|
+
*/
|
|
26
|
+
getUserData(req: import("express").Request): Promise<OAuthUserData>;
|
|
27
|
+
/**
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
30
|
+
getProviderName(): string;
|
|
31
|
+
}
|
|
32
|
+
export type AuthConfig = import("../types.js").AuthConfig;
|
|
33
|
+
export type OAuthUserData = import("../types.js").OAuthUserData;
|
|
34
|
+
export type AzureProviderConfig = import("../types.js").AzureProviderConfig;
|
|
35
|
+
import { BaseOAuthProvider } from "./base-provider.js";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../types.js").AuthConfig} AuthConfig
|
|
3
|
+
* @typedef {import("../types.js").OAuthUserData} OAuthUserData
|
|
4
|
+
* @typedef {import("../types.js").OAuthCallbackResult} OAuthCallbackResult
|
|
5
|
+
* @typedef {import("../types.js").OAuthProviderConfig} OAuthProviderConfig
|
|
6
|
+
*/
|
|
7
|
+
export class BaseOAuthProvider {
|
|
8
|
+
/**
|
|
9
|
+
* @param {OAuthProviderConfig} config
|
|
10
|
+
* @param {AuthConfig} authConfig
|
|
11
|
+
* @param {import("../auth-manager.js").AuthManager} authManager
|
|
12
|
+
*/
|
|
13
|
+
constructor(config: OAuthProviderConfig, authConfig: AuthConfig, authManager: import("../auth-manager.js").AuthManager);
|
|
14
|
+
config: import("../types.js").OAuthProviderConfig;
|
|
15
|
+
authConfig: import("../types.js").AuthConfig;
|
|
16
|
+
authManager: import("../auth-manager.js").AuthManager;
|
|
17
|
+
/**
|
|
18
|
+
* Handle an OAuth provider callback request and resolve the login.
|
|
19
|
+
* @param {import("express").Request} req
|
|
20
|
+
* @returns {Promise<OAuthCallbackResult>}
|
|
21
|
+
*/
|
|
22
|
+
handleCallback(req: import("express").Request): Promise<OAuthCallbackResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve or create an account for the OAuth user and record the login.
|
|
25
|
+
* @param {OAuthUserData} userData
|
|
26
|
+
* @param {import("express").Request} req
|
|
27
|
+
* @returns {Promise<OAuthCallbackResult>}
|
|
28
|
+
* @throws {Error} when an account already exists for the user's email
|
|
29
|
+
*/
|
|
30
|
+
processOAuthLogin(userData: OAuthUserData, req: import("express").Request): Promise<OAuthCallbackResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Exchange an authorization code for an access token.
|
|
33
|
+
* @param {string} code
|
|
34
|
+
* @param {string} tokenUrl
|
|
35
|
+
* @returns {Promise<string>}
|
|
36
|
+
* @throws {Error} when the exchange fails or no access token is returned
|
|
37
|
+
*/
|
|
38
|
+
exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Fetch the authenticated user profile from a provider API.
|
|
41
|
+
* @param {string} accessToken
|
|
42
|
+
* @param {string} apiUrl
|
|
43
|
+
* @param {Record<string, string>} [headers]
|
|
44
|
+
* @returns {Promise<any>}
|
|
45
|
+
* @throws {Error} when the request fails
|
|
46
|
+
*/
|
|
47
|
+
fetchUserFromAPI(accessToken: string, apiUrl: string, headers?: Record<string, string>): Promise<any>;
|
|
48
|
+
}
|
|
49
|
+
export type AuthConfig = import("../types.js").AuthConfig;
|
|
50
|
+
export type OAuthUserData = import("../types.js").OAuthUserData;
|
|
51
|
+
export type OAuthCallbackResult = import("../types.js").OAuthCallbackResult;
|
|
52
|
+
export type OAuthProviderConfig = import("../types.js").OAuthProviderConfig;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../types.js").AuthConfig} AuthConfig
|
|
3
|
+
* @typedef {import("../types.js").OAuthUserData} OAuthUserData
|
|
4
|
+
* @typedef {import("../types.js").GitHubProviderConfig} GitHubProviderConfig
|
|
5
|
+
*/
|
|
6
|
+
export class GitHubProvider extends BaseOAuthProvider {
|
|
7
|
+
/**
|
|
8
|
+
* Build the GitHub authorization URL.
|
|
9
|
+
* @param {string} [state]
|
|
10
|
+
* @param {string[]} [scopes]
|
|
11
|
+
* @returns {string}
|
|
12
|
+
*/
|
|
13
|
+
getAuthUrl(state?: string, scopes?: string[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* Exchange the callback code and resolve the GitHub user profile.
|
|
16
|
+
* @param {import("express").Request} req
|
|
17
|
+
* @returns {Promise<OAuthUserData>}
|
|
18
|
+
* @throws {Error} when no code is provided or no verified email is found
|
|
19
|
+
*/
|
|
20
|
+
getUserData(req: import("express").Request): Promise<OAuthUserData>;
|
|
21
|
+
/**
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
getProviderName(): string;
|
|
25
|
+
}
|
|
26
|
+
export type AuthConfig = import("../types.js").AuthConfig;
|
|
27
|
+
export type OAuthUserData = import("../types.js").OAuthUserData;
|
|
28
|
+
export type GitHubProviderConfig = import("../types.js").GitHubProviderConfig;
|
|
29
|
+
import { BaseOAuthProvider } from "./base-provider.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../types.js").AuthConfig} AuthConfig
|
|
3
|
+
* @typedef {import("../types.js").OAuthUserData} OAuthUserData
|
|
4
|
+
* @typedef {import("../types.js").GoogleProviderConfig} GoogleProviderConfig
|
|
5
|
+
*/
|
|
6
|
+
export class GoogleProvider extends BaseOAuthProvider {
|
|
7
|
+
/**
|
|
8
|
+
* Build the Google authorization URL.
|
|
9
|
+
* @param {string} [state]
|
|
10
|
+
* @param {string[]} [scopes]
|
|
11
|
+
* @returns {string}
|
|
12
|
+
*/
|
|
13
|
+
getAuthUrl(state?: string, scopes?: string[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* Exchange the callback code and resolve the Google user profile.
|
|
16
|
+
* @param {import("express").Request} req
|
|
17
|
+
* @returns {Promise<OAuthUserData>}
|
|
18
|
+
* @throws {Error} when no code is provided or no email is found
|
|
19
|
+
*/
|
|
20
|
+
getUserData(req: import("express").Request): Promise<OAuthUserData>;
|
|
21
|
+
/**
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
getProviderName(): string;
|
|
25
|
+
}
|
|
26
|
+
export type AuthConfig = import("../types.js").AuthConfig;
|
|
27
|
+
export type OAuthUserData = import("../types.js").OAuthUserData;
|
|
28
|
+
export type GoogleProviderConfig = import("../types.js").GoogleProviderConfig;
|
|
29
|
+
import { BaseOAuthProvider } from "./base-provider.js";
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./types.js").AuthConfig} AuthConfig
|
|
3
|
+
* @typedef {import("./types.js").AuthAccount} AuthAccount
|
|
4
|
+
* @typedef {import("./types.js").AuthConfirmation} AuthConfirmation
|
|
5
|
+
* @typedef {import("./types.js").AuthRemember} AuthRemember
|
|
6
|
+
* @typedef {import("./types.js").AuthReset} AuthReset
|
|
7
|
+
* @typedef {import("./types.js").AuthProvider} AuthProvider
|
|
8
|
+
* @typedef {import("./types.js").TwoFactorMethod} TwoFactorMethod
|
|
9
|
+
* @typedef {import("./types.js").TwoFactorToken} TwoFactorToken
|
|
10
|
+
* @typedef {import("./types.js").TwoFactorMechanism} TwoFactorMechanism
|
|
11
|
+
*/
|
|
12
|
+
export class AuthQueries {
|
|
13
|
+
/**
|
|
14
|
+
* @param {AuthConfig} config
|
|
15
|
+
*/
|
|
16
|
+
constructor(config: AuthConfig);
|
|
17
|
+
config: import("./types.js").AuthConfig;
|
|
18
|
+
db: import("pg").Pool;
|
|
19
|
+
tablePrefix: string;
|
|
20
|
+
get accountsTable(): string;
|
|
21
|
+
get confirmationsTable(): string;
|
|
22
|
+
get remembersTable(): string;
|
|
23
|
+
get resetsTable(): string;
|
|
24
|
+
get providersTable(): string;
|
|
25
|
+
get twoFactorMethodsTable(): string;
|
|
26
|
+
get twoFactorTokensTable(): string;
|
|
27
|
+
/**
|
|
28
|
+
* @param {number} id
|
|
29
|
+
* @returns {Promise<AuthAccount | null>}
|
|
30
|
+
*/
|
|
31
|
+
findAccountById(id: number): Promise<AuthAccount | null>;
|
|
32
|
+
/**
|
|
33
|
+
* @param {string | number} userId
|
|
34
|
+
* @returns {Promise<AuthAccount | null>}
|
|
35
|
+
*/
|
|
36
|
+
findAccountByUserId(userId: string | number): Promise<AuthAccount | null>;
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} email
|
|
39
|
+
* @returns {Promise<AuthAccount | null>}
|
|
40
|
+
*/
|
|
41
|
+
findAccountByEmail(email: string): Promise<AuthAccount | null>;
|
|
42
|
+
/**
|
|
43
|
+
* List accounts with optional email search, newest first. Used by the
|
|
44
|
+
* @prsm/devtools admin panel binding.
|
|
45
|
+
* @param {{ limit?: number, offset?: number, search?: string }} [opts]
|
|
46
|
+
* @returns {Promise<AuthAccount[]>}
|
|
47
|
+
*/
|
|
48
|
+
listAccounts({ limit, offset, search }?: {
|
|
49
|
+
limit?: number;
|
|
50
|
+
offset?: number;
|
|
51
|
+
search?: string;
|
|
52
|
+
}): Promise<AuthAccount[]>;
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} [search]
|
|
55
|
+
* @returns {Promise<number>}
|
|
56
|
+
*/
|
|
57
|
+
countAccounts(search?: string): Promise<number>;
|
|
58
|
+
/**
|
|
59
|
+
* @param {{ userId: string | number, email: string, password: string | null, verified: boolean, status: number, rolemask: number }} data
|
|
60
|
+
* @returns {Promise<AuthAccount>}
|
|
61
|
+
*/
|
|
62
|
+
createAccount(data: {
|
|
63
|
+
userId: string | number;
|
|
64
|
+
email: string;
|
|
65
|
+
password: string | null;
|
|
66
|
+
verified: boolean;
|
|
67
|
+
status: number;
|
|
68
|
+
rolemask: number;
|
|
69
|
+
}): Promise<AuthAccount>;
|
|
70
|
+
/**
|
|
71
|
+
* @param {number} id
|
|
72
|
+
* @param {Partial<AuthAccount>} updates
|
|
73
|
+
* @returns {Promise<void>}
|
|
74
|
+
*/
|
|
75
|
+
updateAccount(id: number, updates: Partial<AuthAccount>): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* @param {number} id
|
|
78
|
+
* @returns {Promise<void>}
|
|
79
|
+
*/
|
|
80
|
+
updateAccountLastLogin(id: number): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* @param {number} id
|
|
83
|
+
* @returns {Promise<void>}
|
|
84
|
+
*/
|
|
85
|
+
incrementForceLogout(id: number): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* @param {number} id
|
|
88
|
+
* @returns {Promise<void>}
|
|
89
|
+
*/
|
|
90
|
+
deleteAccount(id: number): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* @param {{ accountId: number, token: string, email: string, expires: Date }} data
|
|
93
|
+
* @returns {Promise<void>}
|
|
94
|
+
*/
|
|
95
|
+
createConfirmation(data: {
|
|
96
|
+
accountId: number;
|
|
97
|
+
token: string;
|
|
98
|
+
email: string;
|
|
99
|
+
expires: Date;
|
|
100
|
+
}): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* @param {string} token
|
|
103
|
+
* @returns {Promise<AuthConfirmation | null>}
|
|
104
|
+
*/
|
|
105
|
+
findConfirmation(token: string): Promise<AuthConfirmation | null>;
|
|
106
|
+
/**
|
|
107
|
+
* @param {number} accountId
|
|
108
|
+
* @returns {Promise<AuthConfirmation | null>}
|
|
109
|
+
*/
|
|
110
|
+
findLatestConfirmationForAccount(accountId: number): Promise<AuthConfirmation | null>;
|
|
111
|
+
/**
|
|
112
|
+
* @param {string} token
|
|
113
|
+
* @returns {Promise<void>}
|
|
114
|
+
*/
|
|
115
|
+
deleteConfirmation(token: string): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* @param {{ accountId: number, token: string, expires: Date }} data
|
|
118
|
+
* @returns {Promise<void>}
|
|
119
|
+
*/
|
|
120
|
+
createRememberToken(data: {
|
|
121
|
+
accountId: number;
|
|
122
|
+
token: string;
|
|
123
|
+
expires: Date;
|
|
124
|
+
}): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* @param {string} token
|
|
127
|
+
* @returns {Promise<AuthRemember | null>}
|
|
128
|
+
*/
|
|
129
|
+
findRememberToken(token: string): Promise<AuthRemember | null>;
|
|
130
|
+
/**
|
|
131
|
+
* @param {string} token
|
|
132
|
+
* @returns {Promise<void>}
|
|
133
|
+
*/
|
|
134
|
+
deleteRememberToken(token: string): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* @param {number} accountId
|
|
137
|
+
* @returns {Promise<void>}
|
|
138
|
+
*/
|
|
139
|
+
deleteRememberTokensForAccount(accountId: number): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* @param {number} accountId
|
|
142
|
+
* @returns {Promise<void>}
|
|
143
|
+
*/
|
|
144
|
+
deleteExpiredRememberTokensForAccount(accountId: number): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* @param {{ accountId: number, token: string, expires: Date }} data
|
|
147
|
+
* @returns {Promise<void>}
|
|
148
|
+
*/
|
|
149
|
+
createResetToken(data: {
|
|
150
|
+
accountId: number;
|
|
151
|
+
token: string;
|
|
152
|
+
expires: Date;
|
|
153
|
+
}): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* @param {string} token
|
|
156
|
+
* @returns {Promise<AuthReset | null>}
|
|
157
|
+
*/
|
|
158
|
+
findResetToken(token: string): Promise<AuthReset | null>;
|
|
159
|
+
/**
|
|
160
|
+
* @param {number} accountId
|
|
161
|
+
* @returns {Promise<number>}
|
|
162
|
+
*/
|
|
163
|
+
countActiveResetTokensForAccount(accountId: number): Promise<number>;
|
|
164
|
+
/**
|
|
165
|
+
* @param {string} token
|
|
166
|
+
* @returns {Promise<void>}
|
|
167
|
+
*/
|
|
168
|
+
deleteResetToken(token: string): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* @param {number} accountId
|
|
171
|
+
* @returns {Promise<void>}
|
|
172
|
+
*/
|
|
173
|
+
deleteResetTokensForAccount(accountId: number): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* @param {{ accountId: number, provider: string, providerId: string, providerEmail: string | null, providerUsername: string | null, providerName: string | null, providerAvatar: string | null }} data
|
|
176
|
+
* @returns {Promise<AuthProvider>}
|
|
177
|
+
*/
|
|
178
|
+
createProvider(data: {
|
|
179
|
+
accountId: number;
|
|
180
|
+
provider: string;
|
|
181
|
+
providerId: string;
|
|
182
|
+
providerEmail: string | null;
|
|
183
|
+
providerUsername: string | null;
|
|
184
|
+
providerName: string | null;
|
|
185
|
+
providerAvatar: string | null;
|
|
186
|
+
}): Promise<AuthProvider>;
|
|
187
|
+
/**
|
|
188
|
+
* @param {string} providerId
|
|
189
|
+
* @param {string} provider
|
|
190
|
+
* @returns {Promise<AuthProvider | null>}
|
|
191
|
+
*/
|
|
192
|
+
findProviderByProviderIdAndType(providerId: string, provider: string): Promise<AuthProvider | null>;
|
|
193
|
+
/**
|
|
194
|
+
* @param {number} accountId
|
|
195
|
+
* @returns {Promise<AuthProvider[]>}
|
|
196
|
+
*/
|
|
197
|
+
findProvidersByAccountId(accountId: number): Promise<AuthProvider[]>;
|
|
198
|
+
/**
|
|
199
|
+
* @param {number} id
|
|
200
|
+
* @returns {Promise<void>}
|
|
201
|
+
*/
|
|
202
|
+
deleteProvider(id: number): Promise<void>;
|
|
203
|
+
/**
|
|
204
|
+
* @param {number} accountId
|
|
205
|
+
* @returns {Promise<void>}
|
|
206
|
+
*/
|
|
207
|
+
deleteProvidersByAccountId(accountId: number): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* @param {number} accountId
|
|
210
|
+
* @returns {Promise<TwoFactorMethod[]>}
|
|
211
|
+
*/
|
|
212
|
+
findTwoFactorMethodsByAccountId(accountId: number): Promise<TwoFactorMethod[]>;
|
|
213
|
+
/**
|
|
214
|
+
* @param {number} accountId
|
|
215
|
+
* @param {TwoFactorMechanism} mechanism
|
|
216
|
+
* @returns {Promise<TwoFactorMethod | null>}
|
|
217
|
+
*/
|
|
218
|
+
findTwoFactorMethodByAccountAndMechanism(accountId: number, mechanism: TwoFactorMechanism): Promise<TwoFactorMethod | null>;
|
|
219
|
+
/**
|
|
220
|
+
* @param {{ accountId: number, mechanism: TwoFactorMechanism, secret?: string, backupCodes?: string[], verified?: boolean }} data
|
|
221
|
+
* @returns {Promise<TwoFactorMethod>}
|
|
222
|
+
*/
|
|
223
|
+
createTwoFactorMethod(data: {
|
|
224
|
+
accountId: number;
|
|
225
|
+
mechanism: TwoFactorMechanism;
|
|
226
|
+
secret?: string;
|
|
227
|
+
backupCodes?: string[];
|
|
228
|
+
verified?: boolean;
|
|
229
|
+
}): Promise<TwoFactorMethod>;
|
|
230
|
+
/**
|
|
231
|
+
* @param {number} id
|
|
232
|
+
* @param {Partial<Pick<TwoFactorMethod, "secret" | "backup_codes" | "verified" | "last_used_at">>} updates
|
|
233
|
+
* @returns {Promise<void>}
|
|
234
|
+
*/
|
|
235
|
+
updateTwoFactorMethod(id: number, updates: Partial<Pick<TwoFactorMethod, "secret" | "backup_codes" | "verified" | "last_used_at">>): Promise<void>;
|
|
236
|
+
/**
|
|
237
|
+
* @param {number} id
|
|
238
|
+
* @returns {Promise<void>}
|
|
239
|
+
*/
|
|
240
|
+
deleteTwoFactorMethod(id: number): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* @param {number} accountId
|
|
243
|
+
* @returns {Promise<void>}
|
|
244
|
+
*/
|
|
245
|
+
deleteTwoFactorMethodsByAccountId(accountId: number): Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* @param {{ accountId: number, mechanism: TwoFactorMechanism, selector: string, tokenHash: string, expiresAt: Date }} data
|
|
248
|
+
* @returns {Promise<TwoFactorToken>}
|
|
249
|
+
*/
|
|
250
|
+
createTwoFactorToken(data: {
|
|
251
|
+
accountId: number;
|
|
252
|
+
mechanism: TwoFactorMechanism;
|
|
253
|
+
selector: string;
|
|
254
|
+
tokenHash: string;
|
|
255
|
+
expiresAt: Date;
|
|
256
|
+
}): Promise<TwoFactorToken>;
|
|
257
|
+
/**
|
|
258
|
+
* @param {string} selector
|
|
259
|
+
* @returns {Promise<TwoFactorToken | null>}
|
|
260
|
+
*/
|
|
261
|
+
findTwoFactorTokenBySelector(selector: string): Promise<TwoFactorToken | null>;
|
|
262
|
+
/**
|
|
263
|
+
* @param {number} id
|
|
264
|
+
* @returns {Promise<void>}
|
|
265
|
+
*/
|
|
266
|
+
deleteTwoFactorToken(id: number): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* @param {number} accountId
|
|
269
|
+
* @returns {Promise<void>}
|
|
270
|
+
*/
|
|
271
|
+
deleteTwoFactorTokensByAccountId(accountId: number): Promise<void>;
|
|
272
|
+
/**
|
|
273
|
+
* @param {number} accountId
|
|
274
|
+
* @param {TwoFactorMechanism} mechanism
|
|
275
|
+
* @returns {Promise<void>}
|
|
276
|
+
*/
|
|
277
|
+
deleteTwoFactorTokensByAccountAndMechanism(accountId: number, mechanism: TwoFactorMechanism): Promise<void>;
|
|
278
|
+
}
|
|
279
|
+
export type AuthConfig = import("./types.js").AuthConfig;
|
|
280
|
+
export type AuthAccount = import("./types.js").AuthAccount;
|
|
281
|
+
export type AuthConfirmation = import("./types.js").AuthConfirmation;
|
|
282
|
+
export type AuthRemember = import("./types.js").AuthRemember;
|
|
283
|
+
export type AuthReset = import("./types.js").AuthReset;
|
|
284
|
+
export type AuthProvider = import("./types.js").AuthProvider;
|
|
285
|
+
export type TwoFactorMethod = import("./types.js").TwoFactorMethod;
|
|
286
|
+
export type TwoFactorToken = import("./types.js").TwoFactorToken;
|
|
287
|
+
export type TwoFactorMechanism = any;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("./types.js").AuthConfig} AuthConfig
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create all auth tables and indexes. Must run before the first request uses auth.
|
|
6
|
+
* @param {AuthConfig} config
|
|
7
|
+
* @returns {Promise<void>}
|
|
8
|
+
*/
|
|
9
|
+
export function createAuthTables(config: AuthConfig): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* @param {AuthConfig} config
|
|
12
|
+
* @returns {Promise<void>}
|
|
13
|
+
*/
|
|
14
|
+
export function dropAuthTables(config: AuthConfig): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* @param {AuthConfig} config
|
|
17
|
+
* @returns {Promise<void>}
|
|
18
|
+
*/
|
|
19
|
+
export function cleanupExpiredTokens(config: AuthConfig): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* @param {AuthConfig} config
|
|
22
|
+
* @returns {Promise<{ accounts: number, providers: number, confirmations: number, remembers: number, resets: number, twoFactorMethods: number, twoFactorTokens: number, expiredConfirmations: number, expiredRemembers: number, expiredResets: number, expiredTwoFactorTokens: number }>}
|
|
23
|
+
*/
|
|
24
|
+
export function getAuthTableStats(config: AuthConfig): Promise<{
|
|
25
|
+
accounts: number;
|
|
26
|
+
providers: number;
|
|
27
|
+
confirmations: number;
|
|
28
|
+
remembers: number;
|
|
29
|
+
resets: number;
|
|
30
|
+
twoFactorMethods: number;
|
|
31
|
+
twoFactorTokens: number;
|
|
32
|
+
expiredConfirmations: number;
|
|
33
|
+
expiredRemembers: number;
|
|
34
|
+
expiredResets: number;
|
|
35
|
+
expiredTwoFactorTokens: number;
|
|
36
|
+
}>;
|
|
37
|
+
export type AuthConfig = import("./types.js").AuthConfig;
|