@technomoron/api-server-base 2.0.0-beta.2 → 2.0.0-beta.4
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/dist/cjs/api-server-base.cjs +2 -2
- package/dist/cjs/api-server-base.d.ts +4 -4
- package/dist/cjs/auth-api/auth-module.d.ts +11 -2
- package/dist/cjs/auth-api/auth-module.js +179 -43
- package/dist/cjs/auth-api/compat-auth-storage.d.ts +7 -5
- package/dist/cjs/auth-api/compat-auth-storage.js +15 -3
- package/dist/cjs/auth-api/mem-auth-store.d.ts +5 -3
- package/dist/cjs/auth-api/mem-auth-store.js +7 -1
- package/dist/cjs/auth-api/sql-auth-store.d.ts +5 -3
- package/dist/cjs/auth-api/sql-auth-store.js +7 -1
- package/dist/cjs/auth-api/storage.d.ts +6 -4
- package/dist/cjs/auth-api/storage.js +15 -5
- package/dist/cjs/auth-api/types.d.ts +7 -2
- package/dist/cjs/index.cjs +4 -4
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/passkey/base.d.ts +1 -0
- package/dist/cjs/passkey/memory.d.ts +1 -0
- package/dist/cjs/passkey/memory.js +4 -0
- package/dist/cjs/passkey/sequelize.d.ts +1 -0
- package/dist/cjs/passkey/sequelize.js +11 -2
- package/dist/cjs/passkey/service.d.ts +5 -2
- package/dist/cjs/passkey/service.js +6 -0
- package/dist/cjs/passkey/types.d.ts +3 -0
- package/dist/esm/api-server-base.d.ts +4 -4
- package/dist/esm/api-server-base.js +3 -3
- package/dist/esm/auth-api/auth-module.d.ts +11 -2
- package/dist/esm/auth-api/auth-module.js +179 -43
- package/dist/esm/auth-api/compat-auth-storage.d.ts +7 -5
- package/dist/esm/auth-api/compat-auth-storage.js +13 -1
- package/dist/esm/auth-api/mem-auth-store.d.ts +5 -3
- package/dist/esm/auth-api/mem-auth-store.js +8 -2
- package/dist/esm/auth-api/sql-auth-store.d.ts +5 -3
- package/dist/esm/auth-api/sql-auth-store.js +8 -2
- package/dist/esm/auth-api/storage.d.ts +6 -4
- package/dist/esm/auth-api/storage.js +13 -3
- package/dist/esm/auth-api/types.d.ts +7 -2
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/passkey/base.d.ts +1 -0
- package/dist/esm/passkey/memory.d.ts +1 -0
- package/dist/esm/passkey/memory.js +4 -0
- package/dist/esm/passkey/sequelize.d.ts +1 -0
- package/dist/esm/passkey/sequelize.js +11 -2
- package/dist/esm/passkey/service.d.ts +5 -2
- package/dist/esm/passkey/service.js +6 -0
- package/dist/esm/passkey/types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { MemoryOAuthStore } from '../oauth/memory.js';
|
|
|
2
2
|
import { MemoryPasskeyStore } from '../passkey/memory.js';
|
|
3
3
|
import { MemoryTokenStore } from '../token/memory.js';
|
|
4
4
|
import { MemoryUserStore } from '../user/memory.js';
|
|
5
|
-
import {
|
|
5
|
+
import { CompositeAuthAdapter } from './compat-auth-storage.js';
|
|
6
6
|
const DEFAULT_PASSKEY_CONFIG = {
|
|
7
7
|
rpId: 'localhost',
|
|
8
8
|
rpName: 'API Server',
|
|
@@ -56,7 +56,7 @@ export class MemAuthStore {
|
|
|
56
56
|
passkeyStore = new MemoryPasskeyStore({ resolveUser });
|
|
57
57
|
this.passkeyStore = passkeyStore;
|
|
58
58
|
}
|
|
59
|
-
this.adapter = new
|
|
59
|
+
this.adapter = new CompositeAuthAdapter({
|
|
60
60
|
userStore: this.userStore,
|
|
61
61
|
tokenStore: this.tokenStore,
|
|
62
62
|
passkeys: passkeyStore && passkeyConfig ? { store: passkeyStore, config: passkeyConfig } : undefined,
|
|
@@ -113,6 +113,12 @@ export class MemAuthStore {
|
|
|
113
113
|
async verifyPasskeyResponse(params) {
|
|
114
114
|
return this.adapter.verifyPasskeyResponse(params);
|
|
115
115
|
}
|
|
116
|
+
async listUserCredentials(userId) {
|
|
117
|
+
return this.adapter.listUserCredentials(userId);
|
|
118
|
+
}
|
|
119
|
+
async deletePasskeyCredential(credentialId) {
|
|
120
|
+
return this.adapter.deletePasskeyCredential(credentialId);
|
|
121
|
+
}
|
|
116
122
|
async getClient(clientId) {
|
|
117
123
|
return this.adapter.getClient(clientId);
|
|
118
124
|
}
|
|
@@ -3,9 +3,9 @@ import { SequelizeOAuthStore, type SequelizeOAuthStoreOptions } from '../oauth/s
|
|
|
3
3
|
import { SequelizePasskeyStore } from '../passkey/sequelize.js';
|
|
4
4
|
import { type SequelizeTokenStoreOptions } from '../token/sequelize.js';
|
|
5
5
|
import { SequelizeUserStore, type AuthUserAttributes, GenericUserModel, GenericUserModelStatic } from '../user/sequelize.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { AuthAdapter, AuthIdentifier } from './types.js';
|
|
7
7
|
import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
|
|
8
|
-
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyServiceConfig, PasskeyUserDescriptor, PasskeyVerificationParams, PasskeyVerificationResult } from '../passkey/types.js';
|
|
8
|
+
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyServiceConfig, PasskeyUserDescriptor, StoredPasskeyCredential, PasskeyVerificationParams, PasskeyVerificationResult } from '../passkey/types.js';
|
|
9
9
|
import type { TokenStore } from '../token/base.js';
|
|
10
10
|
import type { Token } from '../token/types.js';
|
|
11
11
|
interface PasskeyOptions extends Partial<PasskeyServiceConfig> {
|
|
@@ -30,7 +30,7 @@ export interface SqlAuthStoreParams<UserAttributes extends AuthUserAttributes =
|
|
|
30
30
|
tokenStoreOptions?: Omit<SequelizeTokenStoreOptions, 'sequelize'>;
|
|
31
31
|
oauthStoreOptions?: Omit<SequelizeOAuthStoreOptions, 'sequelize'>;
|
|
32
32
|
}
|
|
33
|
-
export declare class SqlAuthStore<UserAttributes extends AuthUserAttributes = AuthUserAttributes, PublicUserShape extends Omit<UserAttributes, 'password'> = Omit<UserAttributes, 'password'>> implements
|
|
33
|
+
export declare class SqlAuthStore<UserAttributes extends AuthUserAttributes = AuthUserAttributes, PublicUserShape extends Omit<UserAttributes, 'password'> = Omit<UserAttributes, 'password'>> implements AuthAdapter<UserAttributes, PublicUserShape> {
|
|
34
34
|
readonly userStore: SequelizeUserStore<UserAttributes, PublicUserShape>;
|
|
35
35
|
readonly tokenStore: TokenStore;
|
|
36
36
|
readonly passkeyStore?: SequelizePasskeyStore;
|
|
@@ -63,6 +63,8 @@ export declare class SqlAuthStore<UserAttributes extends AuthUserAttributes = Au
|
|
|
63
63
|
}): Promise<boolean>;
|
|
64
64
|
createPasskeyChallenge(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
|
|
65
65
|
verifyPasskeyResponse(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
|
|
66
|
+
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
67
|
+
deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
66
68
|
getClient(clientId: string): Promise<OAuthClient | null>;
|
|
67
69
|
verifyClientSecret(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
|
|
68
70
|
createAuthCode(request: AuthCodeRequest): Promise<AuthCodeData>;
|
|
@@ -2,7 +2,7 @@ import { SequelizeOAuthStore } from '../oauth/sequelize.js';
|
|
|
2
2
|
import { SequelizePasskeyStore } from '../passkey/sequelize.js';
|
|
3
3
|
import { SequelizeTokenStore } from '../token/sequelize.js';
|
|
4
4
|
import { SequelizeUserStore } from '../user/sequelize.js';
|
|
5
|
-
import {
|
|
5
|
+
import { CompositeAuthAdapter } from './compat-auth-storage.js';
|
|
6
6
|
const DEFAULT_PASSKEY_CONFIG = {
|
|
7
7
|
rpId: 'localhost',
|
|
8
8
|
rpName: 'API Server',
|
|
@@ -69,7 +69,7 @@ export class SqlAuthStore {
|
|
|
69
69
|
passkeyStore = new SequelizePasskeyStore({ sequelize: this.sequelize, resolveUser });
|
|
70
70
|
this.passkeyStore = passkeyStore;
|
|
71
71
|
}
|
|
72
|
-
this.adapter = new
|
|
72
|
+
this.adapter = new CompositeAuthAdapter({
|
|
73
73
|
userStore: this.userStore,
|
|
74
74
|
tokenStore: this.tokenStore,
|
|
75
75
|
passkeys: passkeyStore && passkeyConfig ? { store: passkeyStore, config: passkeyConfig } : undefined,
|
|
@@ -144,6 +144,12 @@ export class SqlAuthStore {
|
|
|
144
144
|
async verifyPasskeyResponse(params) {
|
|
145
145
|
return this.adapter.verifyPasskeyResponse(params);
|
|
146
146
|
}
|
|
147
|
+
async listUserCredentials(userId) {
|
|
148
|
+
return this.adapter.listUserCredentials(userId);
|
|
149
|
+
}
|
|
150
|
+
async deletePasskeyCredential(credentialId) {
|
|
151
|
+
return this.adapter.deletePasskeyCredential(credentialId);
|
|
152
|
+
}
|
|
147
153
|
async getClient(clientId) {
|
|
148
154
|
return this.adapter.getClient(clientId);
|
|
149
155
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AuthAdapter, AuthIdentifier } from './types.js';
|
|
2
2
|
import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
|
|
3
|
-
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult } from '../passkey/types.js';
|
|
3
|
+
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult, StoredPasskeyCredential } from '../passkey/types.js';
|
|
4
4
|
import type { Token } from '../token/types.js';
|
|
5
|
-
export declare class
|
|
5
|
+
export declare class BaseAuthAdapter<UserRow = unknown, SafeUser = unknown> implements AuthAdapter<UserRow, SafeUser> {
|
|
6
6
|
getUser(identifier: AuthIdentifier): Promise<UserRow | null>;
|
|
7
7
|
getUserPasswordHash(user: UserRow): string;
|
|
8
8
|
getUserId(user: UserRow): AuthIdentifier;
|
|
@@ -24,6 +24,8 @@ export declare class BaseAuthStorage<UserRow = unknown, SafeUser = unknown> impl
|
|
|
24
24
|
}): Promise<boolean>;
|
|
25
25
|
createPasskeyChallenge(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
|
|
26
26
|
verifyPasskeyResponse(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
|
|
27
|
+
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
28
|
+
deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
27
29
|
getClient(clientId: string): Promise<OAuthClient | null>;
|
|
28
30
|
verifyClientSecret(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
|
|
29
31
|
createAuthCode(request: AuthCodeRequest): Promise<AuthCodeData>;
|
|
@@ -33,4 +35,4 @@ export declare class BaseAuthStorage<UserRow = unknown, SafeUser = unknown> impl
|
|
|
33
35
|
effectiveUserId: AuthIdentifier;
|
|
34
36
|
}): Promise<boolean>;
|
|
35
37
|
}
|
|
36
|
-
export declare const
|
|
38
|
+
export declare const nullAuthAdapter: AuthAdapter<unknown, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Handy base you can extend when wiring a real
|
|
1
|
+
// Handy base you can extend when wiring a real auth adapter. Every method
|
|
2
2
|
// throws by default so unimplemented hooks fail loudly.
|
|
3
|
-
export class
|
|
3
|
+
export class BaseAuthAdapter {
|
|
4
4
|
// Override to load a user record by identifier
|
|
5
5
|
async getUser(identifier) {
|
|
6
6
|
void identifier;
|
|
@@ -57,6 +57,16 @@ export class BaseAuthStorage {
|
|
|
57
57
|
void params;
|
|
58
58
|
throw new Error('Auth storage not configured');
|
|
59
59
|
}
|
|
60
|
+
// Override to list passkey credentials for a user
|
|
61
|
+
async listUserCredentials(userId) {
|
|
62
|
+
void userId;
|
|
63
|
+
throw new Error('Auth storage not configured');
|
|
64
|
+
}
|
|
65
|
+
// Override to delete a passkey credential
|
|
66
|
+
async deletePasskeyCredential(credentialId) {
|
|
67
|
+
void credentialId;
|
|
68
|
+
throw new Error('Auth storage not configured');
|
|
69
|
+
}
|
|
60
70
|
// Override to fetch an OAuth client by identifier
|
|
61
71
|
async getClient(clientId) {
|
|
62
72
|
void clientId;
|
|
@@ -85,4 +95,4 @@ export class BaseAuthStorage {
|
|
|
85
95
|
return false;
|
|
86
96
|
}
|
|
87
97
|
}
|
|
88
|
-
export const
|
|
98
|
+
export const nullAuthAdapter = new BaseAuthAdapter();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
|
|
2
|
-
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult } from '../passkey/types.js';
|
|
2
|
+
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult, StoredPasskeyCredential } from '../passkey/types.js';
|
|
3
3
|
import type { Token } from '../token/types.js';
|
|
4
4
|
export type AuthIdentifier = string | number;
|
|
5
|
-
|
|
5
|
+
/** @internal */
|
|
6
|
+
export interface AuthAdapter<UserRow, SafeUser> {
|
|
6
7
|
getUser(identifier: AuthIdentifier): Promise<UserRow | null>;
|
|
7
8
|
getUserPasswordHash(user: UserRow): string;
|
|
8
9
|
getUserId(user: UserRow): AuthIdentifier;
|
|
@@ -18,6 +19,8 @@ export interface AuthStorage<UserRow, SafeUser> {
|
|
|
18
19
|
}): Promise<boolean>;
|
|
19
20
|
createPasskeyChallenge?(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
|
|
20
21
|
verifyPasskeyResponse?(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
|
|
22
|
+
listUserCredentials?(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
23
|
+
deletePasskeyCredential?(credentialId: Buffer | string): Promise<boolean>;
|
|
21
24
|
getClient?(clientId: string): Promise<OAuthClient | null>;
|
|
22
25
|
verifyClientSecret?(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
|
|
23
26
|
createAuthCode?(request: AuthCodeRequest): Promise<AuthCodeData>;
|
|
@@ -27,3 +30,5 @@ export interface AuthStorage<UserRow, SafeUser> {
|
|
|
27
30
|
effectiveUserId: AuthIdentifier;
|
|
28
31
|
}): Promise<boolean>;
|
|
29
32
|
}
|
|
33
|
+
/** @internal */
|
|
34
|
+
export type AuthStorage<UserRow, SafeUser> = AuthAdapter<UserRow, SafeUser>;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -2,14 +2,14 @@ export { default as ApiServer } from './api-server-base.js';
|
|
|
2
2
|
export { ApiError } from './api-server-base.js';
|
|
3
3
|
export { ApiModule } from './api-module.js';
|
|
4
4
|
export type { ApiErrorParams, ApiHandler, ApiKey, ApiServerConf, ApiRequest, ApiRoute, ApiAuthType, ApiAuthClass, ApiTokenData, ExtendedReq } from './api-server-base.js';
|
|
5
|
-
export type { AuthIdentifier
|
|
5
|
+
export type { AuthIdentifier } from './auth-api/types.js';
|
|
6
6
|
export type { Token, TokenPair, TokenStatus } from './token/types.js';
|
|
7
7
|
export type { JwtSignResult, JwtVerifyResult, JwtDecodeResult } from './token/base.js';
|
|
8
8
|
export type { OAuthClient, AuthCodeData, AuthCodeRequest } from './oauth/types.js';
|
|
9
9
|
export type { AuthProviderModule } from './auth-api/module.js';
|
|
10
|
-
export {
|
|
10
|
+
export { nullAuthAdapter, BaseAuthAdapter } from './auth-api/storage.js';
|
|
11
11
|
export { nullAuthModule, BaseAuthModule } from './auth-api/module.js';
|
|
12
|
-
export {
|
|
12
|
+
export { CompositeAuthAdapter } from './auth-api/compat-auth-storage.js';
|
|
13
13
|
export { MemAuthStore } from './auth-api/mem-auth-store.js';
|
|
14
14
|
export { SqlAuthStore } from './auth-api/sql-auth-store.js';
|
|
15
15
|
export { default as AuthModule } from './auth-api/auth-module.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { default as ApiServer } from './api-server-base.js';
|
|
2
2
|
export { ApiError } from './api-server-base.js';
|
|
3
3
|
export { ApiModule } from './api-module.js';
|
|
4
|
-
export {
|
|
4
|
+
export { nullAuthAdapter, BaseAuthAdapter } from './auth-api/storage.js';
|
|
5
5
|
export { nullAuthModule, BaseAuthModule } from './auth-api/module.js';
|
|
6
|
-
export {
|
|
6
|
+
export { CompositeAuthAdapter } from './auth-api/compat-auth-storage.js';
|
|
7
7
|
export { MemAuthStore } from './auth-api/mem-auth-store.js';
|
|
8
8
|
export { SqlAuthStore } from './auth-api/sql-auth-store.js';
|
|
9
9
|
export { default as AuthModule } from './auth-api/auth-module.js';
|
|
@@ -6,6 +6,7 @@ export declare abstract class PasskeyStore implements PasskeyStorageAdapter {
|
|
|
6
6
|
login?: string;
|
|
7
7
|
}): Promise<PasskeyUserDescriptor | null>;
|
|
8
8
|
abstract listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
9
|
+
abstract deleteCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
9
10
|
abstract findCredentialById(credentialId: Buffer): Promise<StoredPasskeyCredential | null>;
|
|
10
11
|
abstract saveCredential(record: StoredPasskeyCredential): Promise<void>;
|
|
11
12
|
abstract updateCredentialCounter(credentialId: Buffer, counter: number): Promise<void>;
|
|
@@ -17,6 +17,7 @@ export declare class MemoryPasskeyStore extends PasskeyStore {
|
|
|
17
17
|
login?: string;
|
|
18
18
|
}): Promise<PasskeyUserDescriptor | null>;
|
|
19
19
|
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
20
|
+
deleteCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
20
21
|
findCredentialById(credentialId: Buffer): Promise<StoredPasskeyCredential | null>;
|
|
21
22
|
saveCredential(record: StoredPasskeyCredential): Promise<void>;
|
|
22
23
|
updateCredentialCounter(credentialId: Buffer, counter: number): Promise<void>;
|
|
@@ -34,6 +34,10 @@ export class MemoryPasskeyStore extends PasskeyStore {
|
|
|
34
34
|
.filter((record) => normalizeUserId(record.userId) === normalizedUserId)
|
|
35
35
|
.map((record) => cloneCredential(record));
|
|
36
36
|
}
|
|
37
|
+
async deleteCredential(credentialId) {
|
|
38
|
+
const key = encodeCredentialId(credentialId);
|
|
39
|
+
return this.credentials.delete(key);
|
|
40
|
+
}
|
|
37
41
|
async findCredentialById(credentialId) {
|
|
38
42
|
const record = this.credentials.get(encodeCredentialId(credentialId));
|
|
39
43
|
return record ? cloneCredential(record) : null;
|
|
@@ -44,6 +44,7 @@ export declare class SequelizePasskeyStore extends PasskeyStore {
|
|
|
44
44
|
login?: string;
|
|
45
45
|
}): Promise<PasskeyUserDescriptor | null>;
|
|
46
46
|
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
47
|
+
deleteCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
47
48
|
findCredentialById(credentialId: Buffer): Promise<StoredPasskeyCredential | null>;
|
|
48
49
|
saveCredential(record: StoredPasskeyCredential): Promise<void>;
|
|
49
50
|
updateCredentialCounter(credentialId: Buffer, counter: number): Promise<void>;
|
|
@@ -144,9 +144,16 @@ export class SequelizePasskeyStore extends PasskeyStore {
|
|
|
144
144
|
counter: model.counter,
|
|
145
145
|
transports: (model.transports ?? undefined),
|
|
146
146
|
backedUp: model.backedUp,
|
|
147
|
-
deviceType: model.deviceType
|
|
147
|
+
deviceType: model.deviceType,
|
|
148
|
+
createdAt: model.createdAt ?? undefined,
|
|
149
|
+
updatedAt: model.updatedAt ?? undefined
|
|
148
150
|
}));
|
|
149
151
|
}
|
|
152
|
+
async deleteCredential(credentialId) {
|
|
153
|
+
const encoded = Buffer.isBuffer(credentialId) ? credentialId.toString('base64') : credentialId;
|
|
154
|
+
const deleted = await this.credentials.destroy({ where: { credentialId: encoded } });
|
|
155
|
+
return deleted > 0;
|
|
156
|
+
}
|
|
150
157
|
async findCredentialById(credentialId) {
|
|
151
158
|
const model = await this.credentials.findByPk(encodeCredentialId(credentialId));
|
|
152
159
|
if (!model) {
|
|
@@ -159,7 +166,9 @@ export class SequelizePasskeyStore extends PasskeyStore {
|
|
|
159
166
|
counter: model.counter,
|
|
160
167
|
transports: (model.transports ?? undefined),
|
|
161
168
|
backedUp: model.backedUp,
|
|
162
|
-
deviceType: model.deviceType
|
|
169
|
+
deviceType: model.deviceType,
|
|
170
|
+
createdAt: model.createdAt ?? undefined,
|
|
171
|
+
updatedAt: model.updatedAt ?? undefined
|
|
163
172
|
};
|
|
164
173
|
}
|
|
165
174
|
async saveCredential(record) {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyStorageAdapter, PasskeyVerificationParams, PasskeyVerificationResult, PasskeyServiceConfig } from './types.js';
|
|
2
|
-
|
|
1
|
+
import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyStorageAdapter, PasskeyVerificationParams, PasskeyVerificationResult, PasskeyServiceConfig, StoredPasskeyCredential } from './types.js';
|
|
2
|
+
import type { AuthIdentifier } from '../auth-api/types.js';
|
|
3
|
+
export type { CredentialDeviceType, PasskeyChallenge, PasskeyChallengeParams, PasskeyChallengeRecord, PasskeyChallengeMetadata, PasskeyUserDescriptor, PasskeyVerificationParams, PasskeyVerificationResult, PasskeyServiceConfig, PasskeyStorageAdapter, StoredPasskeyCredential } from './types.js';
|
|
3
4
|
type Logger = Pick<typeof console, 'error' | 'warn'>;
|
|
4
5
|
export declare class PasskeyService {
|
|
5
6
|
private readonly config;
|
|
6
7
|
private readonly adapter;
|
|
7
8
|
private readonly logger;
|
|
8
9
|
constructor(config: PasskeyServiceConfig, adapter: PasskeyStorageAdapter, logger?: Logger);
|
|
10
|
+
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
11
|
+
deleteCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
9
12
|
createChallenge(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
|
|
10
13
|
verifyResponse(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
|
|
11
14
|
private createRegistrationChallenge;
|
|
@@ -37,6 +37,12 @@ export class PasskeyService {
|
|
|
37
37
|
this.adapter = adapter;
|
|
38
38
|
this.logger = logger;
|
|
39
39
|
}
|
|
40
|
+
async listUserCredentials(userId) {
|
|
41
|
+
return this.adapter.listUserCredentials(userId);
|
|
42
|
+
}
|
|
43
|
+
async deleteCredential(credentialId) {
|
|
44
|
+
return this.adapter.deleteCredential(credentialId);
|
|
45
|
+
}
|
|
40
46
|
async createChallenge(params) {
|
|
41
47
|
await this.adapter.cleanupChallenges?.(new Date());
|
|
42
48
|
const metadata = {
|
|
@@ -36,6 +36,8 @@ export interface StoredPasskeyCredential {
|
|
|
36
36
|
transports?: AuthenticatorTransportFuture[];
|
|
37
37
|
backedUp: boolean;
|
|
38
38
|
deviceType: CredentialDeviceType;
|
|
39
|
+
createdAt?: Date;
|
|
40
|
+
updatedAt?: Date;
|
|
39
41
|
}
|
|
40
42
|
export interface PasskeyStorageAdapter {
|
|
41
43
|
resolveUser(params: {
|
|
@@ -43,6 +45,7 @@ export interface PasskeyStorageAdapter {
|
|
|
43
45
|
login?: string;
|
|
44
46
|
}): Promise<PasskeyUserDescriptor | null>;
|
|
45
47
|
listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
|
|
48
|
+
deleteCredential(credentialId: Buffer | string): Promise<boolean>;
|
|
46
49
|
findCredentialById(credentialId: Buffer): Promise<StoredPasskeyCredential | null>;
|
|
47
50
|
saveCredential(record: StoredPasskeyCredential): Promise<void>;
|
|
48
51
|
updateCredentialCounter(credentialId: Buffer, counter: number): Promise<void>;
|