@unchainedshop/core-users 4.3.5 → 4.5.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.
Files changed (45) hide show
  1. package/README.md +124 -2
  2. package/lib/db/UsersCollection.d.ts +8 -5
  3. package/lib/db/UsersCollection.js +0 -1
  4. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.d.ts +1 -2
  5. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.js +0 -1
  6. package/lib/migrations/20241218092300-convert-locale.d.ts +2 -0
  7. package/lib/migrations/20241218092300-convert-locale.js +36 -0
  8. package/lib/module/configureUsersModule.d.ts +53 -23
  9. package/lib/module/configureUsersModule.js +127 -18
  10. package/lib/module/configureUsersWebAuthnModule.d.ts +78 -20
  11. package/lib/module/configureUsersWebAuthnModule.js +126 -112
  12. package/lib/module/pbkdf2.d.ts +0 -1
  13. package/lib/module/pbkdf2.js +3 -7
  14. package/lib/users-index.d.ts +5 -6
  15. package/lib/users-index.js +5 -6
  16. package/lib/users-settings.d.ts +11 -11
  17. package/lib/users-settings.js +7 -10
  18. package/lib/utils/web3-verification.d.ts +1 -0
  19. package/lib/utils/web3-verification.js +81 -0
  20. package/package.json +26 -16
  21. package/lib/db/UsersCollection.d.ts.map +0 -1
  22. package/lib/db/UsersCollection.js.map +0 -1
  23. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.d.ts.map +0 -1
  24. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.js.map +0 -1
  25. package/lib/module/configureUsersModule.d.ts.map +0 -1
  26. package/lib/module/configureUsersModule.js.map +0 -1
  27. package/lib/module/configureUsersWebAuthnModule.d.ts.map +0 -1
  28. package/lib/module/configureUsersWebAuthnModule.js.map +0 -1
  29. package/lib/module/pbkdf2.d.ts.map +0 -1
  30. package/lib/module/pbkdf2.js.map +0 -1
  31. package/lib/users-index.d.ts.map +0 -1
  32. package/lib/users-index.js.map +0 -1
  33. package/lib/users-settings.d.ts.map +0 -1
  34. package/lib/users-settings.js.map +0 -1
  35. package/src/db/UsersCollection.ts +0 -174
  36. package/src/db/WebAuthnCredentialsCreationRequestsCollection.ts +0 -26
  37. package/src/module/buildFindSelector.test.ts +0 -34
  38. package/src/module/configureUsersModule.ts +0 -857
  39. package/src/module/configureUsersWebAuthnModule.ts +0 -234
  40. package/src/module/pbkdf2.ts +0 -46
  41. package/src/module/removeConfidentialServiceHashes.test.ts +0 -12
  42. package/src/users-index.ts +0 -5
  43. package/src/users-settings.ts +0 -99
  44. package/tests/mock/user-mock.ts +0 -72
  45. package/tsconfig.json +0 -10
@@ -1,234 +0,0 @@
1
- import { ModuleInput } from '@unchainedshop/mongodb';
2
- import { createLogger } from '@unchainedshop/logger';
3
- import { WebAuthnCredentialsCreationRequestsCollection } from '../db/WebAuthnCredentialsCreationRequestsCollection.js';
4
-
5
- import type {
6
- Fido2Lib as Fido2LibType,
7
- PublicKeyCredentialCreationOptions,
8
- PublicKeyCredentialRequestOptions,
9
- } from 'fido2-lib';
10
-
11
- const logger = createLogger('unchained:core-users');
12
-
13
- const { ROOT_URL = 'http://localhost:4010', EMAIL_WEBSITE_NAME = 'Unchained' } = process.env;
14
-
15
- type SerializedOptions<T> = Omit<T, 'challenge' | 'requestId'> & {
16
- challenge: string;
17
- requestId: number;
18
- };
19
-
20
- let Fido2Lib: typeof Fido2LibType;
21
- try {
22
- const fido2LibPackage = await import('fido2-lib');
23
- Fido2Lib = fido2LibPackage.Fido2Lib;
24
- } catch {
25
- logger.warn(`optional peer npm package 'fido2-lib' not installed, WebAuthn will not work`);
26
- }
27
-
28
- let setupMDSPromise;
29
- const setupMDSCollection = async () => {
30
- try {
31
- const tocResult = await fetch('https://mds.fidoalliance.org');
32
- const tocBase64 = await tocResult.text();
33
- const mc = Fido2Lib.createMdsCollection('FIDO MDS v3');
34
- // eslint-disable-next-line
35
- // @ts-ignore
36
- const tocObj = await mc.addToc(tocBase64);
37
- return tocObj.entries;
38
- } catch (e) {
39
- logger.error(e);
40
- return [];
41
- }
42
- };
43
-
44
- const fetchMDS = async () => {
45
- if (setupMDSPromise) return setupMDSPromise;
46
- setupMDSPromise = setupMDSCollection();
47
- return setupMDSPromise;
48
- };
49
-
50
- export function toArrayBuffer(buffer) {
51
- return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
52
- }
53
-
54
- export function buf2hex(buffer) {
55
- // buffer is an ArrayBuffer
56
- return Array.prototype.map
57
- .call(new Uint8Array(buffer), (x) => `00${x.toString(16)}`.slice(-2))
58
- .join('');
59
- }
60
-
61
- export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) => {
62
- const WebAuthnCredentialsCreationRequests = await WebAuthnCredentialsCreationRequestsCollection(db);
63
-
64
- const thisDomain = new URL(ROOT_URL).hostname;
65
- const f2l =
66
- Fido2Lib &&
67
- new Fido2Lib({
68
- rpId: thisDomain,
69
- rpName: EMAIL_WEBSITE_NAME,
70
- rpIcon:
71
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAARCSURBVHgB7Ve9UxNbFL8fm7yA4ktegHnlMk98dMbOMnR2D6pnGTqtCH+BWFoBpZXQaaelFbGzEztHHF26DKizzijDx+Zef+fu3vXuJgsxztjonQnZOZw993d+5zOM/epHslFO1a/KS/UbuvTnETsKQ/YDh3+XNi72yuVlzVgbL1YhCaOTk2ssDAI24hHDKsrpfxZkufwCj6t0OUAEBMkrlR6wHzjDMVCd872yemeete7gczeKoh2wQTICsyi0DrTWVc55eHqwu8OGPEMCMNSby5hS89H7Nx0Se9NXVvF1J69O7MDwJsKzgfCcmSP9SQhvxcV6S5cnummCHYVH4kJ9DE9NfHx1+HGLxKo0sSOkvIXHSnyz7mjOySufdLmUN3Vp4slZiSoyXk7NrhHVQui1fGzhzTq+QsZ5U07NtowQ3oH2FavDhXjS2389w7W+lrDgI2+2yfaZAEpT/y5LopjztnEkf1F6GXsc38TvWKO9g91NfO3EBGgjpxzooTosCISvXQjAm7zc1Fyvm7IChRHQM+uVcxGBAbstI84bVcqyUE3lAMyVWkrky0UsuGUYRqeni4zQk1cAk15ELxMYy07OqElKqo5ieVWWymsDAbhKGa9Qatag8P5omcQiUEot9nmb1c9cFkm5FJPJWqWp2UYegKkCMf7XHjRaeGwgs+9T1iPTA8ibkM/h5ev4XwVJthEd7D7kF+ozANRI9B9RlpO+lUO/IcZqz0jGPr8PUUFU7k185mwFZUIwBAuGUqWUob8nxCqLQ0H6qbeOnNmQGftOBVHO9QEw+ozZRKLE8y0wxDxFLISIE6n7KsDfjUS8kBoludZbCYBvl8XNaCMPLAOASsde5vYAlFPbeqWV+q/Pq5xR6HRS6zkWzPzIlXdmGKWXFaM/V06zwAGQaVppSJ3yzk7DAqpcb7UQD/q8cuRoxb75dtlxm5Zb3mzALEj7O7I/zWRUBRurHcO7G9Sw5MXJT+rLh+dmRlSqe6iOm1aOC/5nBELr2yTDOw3YO4Z+x3icq7iB01BMXm4j4dbIO+rtVi6nr7xLBg0tIjN20mGGbBPdVs+8J07mvcjzkbnbGf14tNNeYcb4wJVMH358jpo2zSf1lgCM1V4m6CsFXiUG9Iref9txe4kQXgVT9jqXejNZaEKAvFu4D5ikStBjus3bJcPxdjALNE8OduetHep+yIsXGQcZf9wTxyusGwSFS2mCvmaMcn6Lj9d9OV77BGN7iOuCYQFeqcMPT43+peln2IraFH/EdsvuALDTTTthvE0tIRnvsc/x/8/diIq2HnsSFoKEhXUAWM6zYA5VwoDtaLiV7O85XypFy+hVnbRlhCXoo9zZHWkpGWY3/L613D25PZFzeVVxvZqs6ywSYKZ7/ro+2g8TOu6eSBXAGfWIio2z2n871GY8OgN06BcSfitQuZr1CxuQ3Zh/6qkk0/P3GeV8BeBCYUHc/WHIAAAAAElFTkSuQmCC',
72
- challengeSize: 128,
73
- attestation: 'none',
74
- });
75
-
76
- return {
77
- findMDSMetadataForAAGUID: async (aaguid: string) => {
78
- const mdsCollection = await fetchMDS();
79
- const foundEntry = mdsCollection.find((entry) => {
80
- return entry.aaguid === aaguid;
81
- });
82
- return foundEntry?.metadataStatement;
83
- },
84
-
85
- createCredentialCreationOptions: async (
86
- origin: string,
87
- username: string,
88
- extensionOptions?: any,
89
- ) => {
90
- if (!f2l) return null;
91
-
92
- const registrationOptions = await f2l.attestationOptions(extensionOptions);
93
- // Convert challenge to base64 without using Buffer
94
- const challenge = btoa(String.fromCharCode(...new Uint8Array(registrationOptions.challenge)));
95
- const { insertedId } = await WebAuthnCredentialsCreationRequests.insertOne({
96
- _id: new Date().getTime(),
97
- challenge,
98
- origin,
99
- factor: (registrationOptions as any).factor || 'either',
100
- username,
101
- });
102
-
103
- return {
104
- ...registrationOptions,
105
- challenge,
106
- requestId: insertedId,
107
- } as SerializedOptions<PublicKeyCredentialCreationOptions>;
108
- },
109
-
110
- createCredentialRequestOptions: async (origin: string, username: string, extensionOptions?: any) => {
111
- if (!f2l) return null;
112
-
113
- const loginOptions = await f2l.assertionOptions(extensionOptions);
114
- // Convert challenge to base64 without using Buffer
115
- const challenge = btoa(String.fromCharCode(...new Uint8Array(loginOptions.challenge)));
116
- const { insertedId } = await WebAuthnCredentialsCreationRequests.insertOne({
117
- _id: new Date().getTime(),
118
- challenge,
119
- origin,
120
- factor: (loginOptions as any).factor || 'either',
121
- username,
122
- });
123
-
124
- return {
125
- ...loginOptions,
126
- challenge,
127
- requestId: insertedId,
128
- } as SerializedOptions<PublicKeyCredentialRequestOptions>;
129
- },
130
-
131
- verifyCredentialCreation: async (username: string, credentials: any) => {
132
- if (!f2l) return null;
133
-
134
- const request = await WebAuthnCredentialsCreationRequests.findOne(
135
- {
136
- username,
137
- },
138
- { sort: { _id: -1 } },
139
- );
140
- if (!request) return null;
141
-
142
- const attestationExpectations = {
143
- challenge: request.challenge,
144
- origin: request.origin,
145
- factor: request.factor,
146
- };
147
-
148
- const id = Buffer.from(credentials.id, 'base64');
149
- const attestationObject = Buffer.from(credentials.response.attestationObject, 'base64');
150
- const clientDataJSON = Buffer.from(credentials.response.clientDataJSON, 'base64');
151
-
152
- const attestationResponse = {
153
- id: toArrayBuffer(id),
154
- response: {
155
- attestationObject: toArrayBuffer(attestationObject),
156
- clientDataJSON: toArrayBuffer(clientDataJSON),
157
- },
158
- };
159
-
160
- const registrationOptions = await f2l.attestationResult(
161
- attestationResponse,
162
- attestationExpectations,
163
- );
164
-
165
- const publicKey = registrationOptions?.authnrData?.get('credentialPublicKeyPem');
166
- const aaguidArrayBuffer = registrationOptions?.authnrData?.get('aaguid'); // ArrayBuffer Uint8...
167
- const counter = registrationOptions?.authnrData?.get('counter');
168
-
169
- const aaguidConcatenated = buf2hex(aaguidArrayBuffer);
170
- const aaguid = `${aaguidConcatenated.slice(0, 8)}-${aaguidConcatenated.slice(
171
- 8,
172
- 12,
173
- )}-${aaguidConcatenated.slice(12, 16)}-${aaguidConcatenated.slice(
174
- 16,
175
- 20,
176
- )}-${aaguidConcatenated.slice(20)}`;
177
-
178
- return { publicKey, counter, id: credentials.id, aaguid, created: new Date() };
179
- },
180
-
181
- verifyCredentialRequest: async (userPublicKeys: any[], username: string, credentials: any) => {
182
- if (!f2l) return null;
183
-
184
- const request = await WebAuthnCredentialsCreationRequests.findOne(
185
- {
186
- _id: credentials.requestId,
187
- },
188
- { sort: { _id: -1 } },
189
- );
190
- if (!request) return null;
191
-
192
- const id = Buffer.from(credentials.id, 'base64');
193
- const authenticatorData = Buffer.from(credentials.response.authenticatorData, 'base64');
194
- const signature = Buffer.from(credentials.response.signature, 'base64');
195
- const userHandle = Buffer.from(credentials.response.userHandle, 'base64');
196
- const clientDataJSON = Buffer.from(credentials.response.clientDataJSON, 'base64');
197
-
198
- const { publicKey, counter } =
199
- userPublicKeys.find((publicCredentials) => {
200
- return credentials.id === publicCredentials.id;
201
- }) || {};
202
-
203
- if (!publicKey) return null;
204
-
205
- const assertionExpectations = {
206
- challenge: request.challenge,
207
- origin: request.origin,
208
- factor: request.factor,
209
- prevCounter: counter,
210
- publicKey,
211
- userHandle: toArrayBuffer(Buffer.from(username)),
212
- };
213
-
214
- const assertionResponse = {
215
- id: toArrayBuffer(id),
216
- response: {
217
- authenticatorData: toArrayBuffer(authenticatorData),
218
- clientDataJSON: toArrayBuffer(clientDataJSON),
219
- signature: toArrayBuffer(signature),
220
- userHandle: toArrayBuffer(userHandle),
221
- },
222
- };
223
-
224
- const loginResult = await f2l.assertionResult(assertionResponse, assertionExpectations);
225
- return { userHandle: loginResult?.authnrData?.get('userHandle') };
226
- },
227
- deleteUserWebAuthnCredentials: async (username: string) => {
228
- const { deletedCount } = await WebAuthnCredentialsCreationRequests.deleteMany({
229
- username,
230
- });
231
- return deletedCount;
232
- },
233
- };
234
- };
@@ -1,46 +0,0 @@
1
- // https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2
2
- const PBKDF2_ITERATIONS = 300000; // Iterations, > 210'000
3
- const PBKDF2_KEY_LENGTH = 256; // Bytes
4
- const PBKDF2_SALT_LENGTH = 16; // Bytes
5
-
6
- export function generateSalt(saltLength = PBKDF2_SALT_LENGTH) {
7
- const array = new Uint8Array(saltLength);
8
- crypto.getRandomValues(array);
9
- // Convert to hex string without using Buffer
10
- return Array.from(array)
11
- .map((b) => b.toString(16).padStart(2, '0'))
12
- .join('');
13
- }
14
-
15
- export async function getDerivedKey(
16
- salt: string,
17
- password: string,
18
- iterations = PBKDF2_ITERATIONS,
19
- keyLength = PBKDF2_KEY_LENGTH,
20
- ) {
21
- const textEncoder = new TextEncoder();
22
- const passwordBuffer = textEncoder.encode(password);
23
- const importedKey = await crypto.subtle.importKey('raw', passwordBuffer, 'PBKDF2', false, [
24
- 'deriveBits',
25
- ]);
26
-
27
- const bits = await crypto.subtle.deriveBits(
28
- {
29
- name: 'PBKDF2',
30
- hash: 'SHA-512',
31
- salt: textEncoder.encode(salt),
32
- iterations,
33
- },
34
- importedKey,
35
- keyLength,
36
- );
37
- // Convert ArrayBuffer to hex string without using Buffer
38
- return Array.from(new Uint8Array(bits))
39
- .map((b) => b.toString(16).padStart(2, '0'))
40
- .join('');
41
- }
42
-
43
- export async function compare(password: string, hash: string, salt: string) {
44
- const comparableHash = await getDerivedKey(salt, password);
45
- return comparableHash === hash;
46
- }
@@ -1,12 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert';
3
- import { removeConfidentialServiceHashes } from './configureUsersModule.js';
4
- import user from '../../tests/mock/user-mock.js';
5
- import { User } from '../db/UsersCollection.js';
6
-
7
- describe('removeConfidentialServiceHashes', () => {
8
- it('Should remove sensitive user credentials ', () => {
9
- assert.notStrictEqual(user.services, undefined);
10
- assert.strictEqual(removeConfidentialServiceHashes(user as unknown as User)?.services, undefined);
11
- });
12
- });
@@ -1,5 +0,0 @@
1
- export * from './db/UsersCollection.js';
2
- export * from './db/WebAuthnCredentialsCreationRequestsCollection.js';
3
- export * from './module/configureUsersModule.js';
4
- export * from './module/configureUsersWebAuthnModule.js';
5
- export * from './users-settings.js';
@@ -1,99 +0,0 @@
1
- import { insensitiveTrimmedRegexOperator, mongodb } from '@unchainedshop/mongodb';
2
- import { User } from './db/UsersCollection.js';
3
- export interface UserRegistrationData extends Partial<User> {
4
- email?: string;
5
- password: string | null;
6
- webAuthnPublicKeyCredentials?: any;
7
- }
8
-
9
- export enum UserAccountAction {
10
- RESET_PASSWORD = 'reset-password',
11
- VERIFY_EMAIL = 'verify-email',
12
- ENROLL_ACCOUNT = 'enroll-account',
13
- PASSWORD_RESETTED = 'password-resetted',
14
- EMAIL_VERIFIED = 'email-verified',
15
- }
16
- export interface UserSettings {
17
- mergeUserCartsOnLogin: boolean;
18
- autoMessagingAfterUserCreation: boolean;
19
- earliestValidTokenDate: (
20
- type: UserAccountAction.VERIFY_EMAIL | UserAccountAction.RESET_PASSWORD,
21
- ) => Date;
22
- validateEmail: (email: string) => Promise<boolean>;
23
- validateUsername: (username: string) => Promise<boolean>;
24
- validateNewUser: (user: UserRegistrationData) => Promise<UserRegistrationData>;
25
- validatePassword: (password: string) => Promise<boolean>;
26
- configureSettings: (options: UserSettingsOptions, db: mongodb.Db) => void;
27
- }
28
-
29
- export type UserSettingsOptions = Omit<Partial<UserSettings>, 'configureSettings'>;
30
-
31
- const defaultAutoMessagingAfterUserCreation = true;
32
- const defaultMergeUserCartsOnLogin = true;
33
-
34
- const defaultEarliestValidTokenDate = () => {
35
- // 1 hour ago
36
- return new Date(new Date().getTime() - 1000 * 60 * 60);
37
- };
38
-
39
- const defaultValidateNewUser = async (user: UserRegistrationData) => {
40
- return {
41
- ...user,
42
- username: user.username?.trim().toLowerCase(),
43
- email: user.email?.trim().toLowerCase(),
44
- password: user.password ?? null,
45
- };
46
- };
47
-
48
- const defaultValidatePassword = async (password: string) => {
49
- return password?.length >= 8;
50
- };
51
-
52
- export const userSettings: UserSettings = {
53
- autoMessagingAfterUserCreation: defaultAutoMessagingAfterUserCreation,
54
- mergeUserCartsOnLogin: defaultMergeUserCartsOnLogin,
55
- earliestValidTokenDate: defaultEarliestValidTokenDate,
56
- validateNewUser: defaultValidateNewUser,
57
- validateEmail: () => Promise.resolve(true),
58
- validateUsername: () => Promise.resolve(true),
59
- validatePassword: () => Promise.resolve(true),
60
-
61
- configureSettings: (
62
- {
63
- mergeUserCartsOnLogin,
64
- autoMessagingAfterUserCreation,
65
- earliestValidTokenDate,
66
- validateEmail,
67
- validateUsername,
68
- validateNewUser,
69
- validatePassword,
70
- },
71
- db: mongodb.Db,
72
- ) => {
73
- const defaultValidateEmail = async (rawEmail: string) => {
74
- if (!rawEmail?.includes?.('@')) return false;
75
- const emailAlreadyExists = await db
76
- .collection('users')
77
- .countDocuments({ 'emails.address': insensitiveTrimmedRegexOperator(rawEmail) }, { limit: 1 });
78
- if (emailAlreadyExists) return false;
79
- return true;
80
- };
81
- const defaultValidateUsername = async (rawUsername: string) => {
82
- if (rawUsername?.length < 3) return false;
83
- const usernameAlreadyExists = await db
84
- .collection('users')
85
- .countDocuments({ username: insensitiveTrimmedRegexOperator(rawUsername) }, { limit: 1 });
86
- if (usernameAlreadyExists) return false;
87
- return true;
88
- };
89
-
90
- userSettings.mergeUserCartsOnLogin = mergeUserCartsOnLogin ?? defaultMergeUserCartsOnLogin;
91
- userSettings.autoMessagingAfterUserCreation =
92
- autoMessagingAfterUserCreation ?? defaultAutoMessagingAfterUserCreation;
93
- userSettings.earliestValidTokenDate = earliestValidTokenDate || defaultEarliestValidTokenDate;
94
- userSettings.validateEmail = validateEmail || defaultValidateEmail;
95
- userSettings.validateUsername = validateUsername || defaultValidateUsername;
96
- userSettings.validateNewUser = validateNewUser || defaultValidateNewUser;
97
- userSettings.validatePassword = validatePassword || defaultValidatePassword;
98
- },
99
- };
@@ -1,72 +0,0 @@
1
- export default {
2
- _id: 'PKve0k9fLCUzn2EUi',
3
- guest: false,
4
- initialPassword: false,
5
- lastBillingAddress: null,
6
- profile: {
7
- address: {
8
- firstName: null,
9
- lastName: null,
10
- company: null,
11
- addressLine: null,
12
- addressLine2: null,
13
- postalCode: null,
14
- regionCode: null,
15
- city: null,
16
- countryCode: null,
17
- },
18
- birthday: new Date('2022-11-21T21:00:00.000Z'),
19
- displayName: null,
20
- gender: null,
21
- phoneMobile: null,
22
- },
23
- roles: ['admin'],
24
- services: {
25
- password: {
26
- bcrypt: '$2a$10$EM5ILD3UtmiP/JJzDvhL3ennDpMEYXfFCCPZ6AiSk3ZM1aPUSjoI2',
27
- reset: [
28
- {
29
- token:
30
- '637dfa08a1a48aba26437de983a6cef32fef369252c97791b81712b2283a1173308efade2666d24dab6aa4',
31
- address: 'admin@unchained.local',
32
- when: new Date('2022-11-26T19:37:30.170Z'),
33
- reason: 'reset',
34
- },
35
- ],
36
- },
37
- token: {
38
- secret: 'secret',
39
- },
40
- webAuthn: [],
41
- web3: [
42
- {
43
- address: '0xF5F72AE7fa1fa990ebaF163208Ed7aD6a3f42DEA',
44
- nonce: '463693',
45
- },
46
- ],
47
- 'two-factor': {
48
- secret: {
49
- base32: 'JF2HO5SAN4YFE7LLKR4FMRSXN47ESVCE',
50
- },
51
- },
52
- },
53
- createdAt: new Date('2022-10-20T17:14:48.834Z'),
54
- updatedAt: new Date('2022-11-26T19:17:57.131Z'),
55
- username: 'admin',
56
- emails: [
57
- {
58
- address: 'admin@unchained.local',
59
- verified: false,
60
- },
61
- ],
62
- lastLogin: {
63
- timestamp: new Date('2022-11-28T16:28:53.202Z'),
64
- remoteAddress: '::ffff:127.0.0.1',
65
- remotePort: 42978,
66
- userAgent:
67
- 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
68
- locale: 'de-CH',
69
- countryCode: 'CH',
70
- },
71
- updated: new Date('2022-11-30T11:02:19.624Z'),
72
- };
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../shared/base.tsconfig.json",
3
- "compilerOptions": {
4
- "declarationDir": "./lib",
5
- "rootDir": "./src",
6
- "outDir": "./lib",
7
-
8
- },
9
- "exclude": ["**/*.test.ts", "**/*.test.js", "tests", "lib"]
10
- }