@appweaver/data 0.0.0-stage → 2.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.
Files changed (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -2
  3. package/config.d.ts +6 -0
  4. package/config.js +22 -0
  5. package/database/create-client.d.ts +11 -0
  6. package/database/create-client.js +145 -0
  7. package/database/database-config.d.ts +14 -0
  8. package/database/database-config.js +40 -0
  9. package/database/database-error.d.ts +49 -0
  10. package/database/database-error.js +216 -0
  11. package/database/index.d.ts +3 -0
  12. package/database/index.js +19 -0
  13. package/database/prisma-database.d.ts +33 -0
  14. package/database/prisma-database.js +178 -0
  15. package/database/run-transaction.d.ts +21 -0
  16. package/database/run-transaction.js +15 -0
  17. package/export/export-config.d.ts +7 -0
  18. package/export/export-config.js +17 -0
  19. package/export/export-service.d.ts +22 -0
  20. package/export/export-service.js +188 -0
  21. package/export/index.d.ts +1 -0
  22. package/export/index.js +17 -0
  23. package/factory/create-model.d.ts +11 -0
  24. package/factory/create-model.js +479 -0
  25. package/factory/create-policy.d.ts +12 -0
  26. package/factory/create-policy.js +20 -0
  27. package/factory/create-service.d.ts +14 -0
  28. package/factory/create-service.js +116 -0
  29. package/index.d.ts +22 -0
  30. package/index.js +38 -0
  31. package/internal.d.ts +2 -0
  32. package/internal.js +6 -0
  33. package/module.d.ts +3 -0
  34. package/module.js +81 -0
  35. package/package.json +67 -3
  36. package/prisma/client/browser.d.ts +39 -0
  37. package/prisma/client/browser.js +56 -0
  38. package/prisma/client/client.d.ts +58 -0
  39. package/prisma/client/client.js +70 -0
  40. package/prisma/client/commonInputTypes.d.ts +345 -0
  41. package/prisma/client/commonInputTypes.js +11 -0
  42. package/prisma/client/enums.d.ts +1 -0
  43. package/prisma/client/enums.js +11 -0
  44. package/prisma/client/internal/class.d.ts +198 -0
  45. package/prisma/client/internal/class.js +85 -0
  46. package/prisma/client/internal/prismaNamespace.d.ts +1125 -0
  47. package/prisma/client/internal/prismaNamespace.js +204 -0
  48. package/prisma/client/internal/prismaNamespaceBrowser.d.ts +137 -0
  49. package/prisma/client/internal/prismaNamespaceBrowser.js +175 -0
  50. package/prisma/client/models/ApiKey.d.ts +1167 -0
  51. package/prisma/client/models/ApiKey.js +2 -0
  52. package/prisma/client/models/ConnectedAccount.d.ts +1094 -0
  53. package/prisma/client/models/ConnectedAccount.js +2 -0
  54. package/prisma/client/models/File.d.ts +1291 -0
  55. package/prisma/client/models/File.js +2 -0
  56. package/prisma/client/models/OneTimeToken.d.ts +1055 -0
  57. package/prisma/client/models/OneTimeToken.js +2 -0
  58. package/prisma/client/models/Permission.d.ts +1209 -0
  59. package/prisma/client/models/Permission.js +2 -0
  60. package/prisma/client/models/Role.d.ts +1209 -0
  61. package/prisma/client/models/Role.js +2 -0
  62. package/prisma/client/models/Seeder.d.ts +1023 -0
  63. package/prisma/client/models/Seeder.js +2 -0
  64. package/prisma/client/models.d.ts +8 -0
  65. package/prisma/client/models.js +2 -0
  66. package/resource/load-data-resources.d.ts +13 -0
  67. package/resource/load-data-resources.js +37 -0
  68. package/resource/model-schema.d.ts +34 -0
  69. package/resource/model-schema.js +54 -0
  70. package/resource/resource-config.d.ts +16 -0
  71. package/resource/resource-config.js +62 -0
  72. package/resource/resource-loader.d.ts +25 -0
  73. package/resource/resource-loader.js +138 -0
  74. package/resource/resource-service.d.ts +462 -0
  75. package/resource/resource-service.js +1042 -0
  76. package/resource/schemas/index.d.ts +3 -0
  77. package/resource/schemas/index.js +19 -0
  78. package/resource/schemas/resource-aggregate-schema.d.ts +53 -0
  79. package/resource/schemas/resource-aggregate-schema.js +130 -0
  80. package/resource/schemas/resource-filter-schema.d.ts +39 -0
  81. package/resource/schemas/resource-filter-schema.js +153 -0
  82. package/resource/schemas/resource-sort-schema.d.ts +38 -0
  83. package/resource/schemas/resource-sort-schema.js +113 -0
  84. package/resource/utils/aggregate-util.d.ts +113 -0
  85. package/resource/utils/aggregate-util.js +322 -0
  86. package/resource/utils/cursor-util.d.ts +60 -0
  87. package/resource/utils/cursor-util.js +116 -0
  88. package/resource/utils/date-util.d.ts +22 -0
  89. package/resource/utils/date-util.js +112 -0
  90. package/resource/utils/delete-util.d.ts +131 -0
  91. package/resource/utils/delete-util.js +385 -0
  92. package/resource/utils/filter-util.d.ts +24 -0
  93. package/resource/utils/filter-util.js +289 -0
  94. package/resource/utils/prune-util.d.ts +11 -0
  95. package/resource/utils/prune-util.js +56 -0
  96. package/resource/utils/relation-util.d.ts +75 -0
  97. package/resource/utils/relation-util.js +400 -0
  98. package/resource/utils/sort-util.d.ts +31 -0
  99. package/resource/utils/sort-util.js +235 -0
  100. package/resource/utils/text-search-util.d.ts +14 -0
  101. package/resource/utils/text-search-util.js +39 -0
  102. package/resources.d.ts +10 -0
  103. package/resources.js +26 -0
  104. package/security/auth-config.d.ts +23 -0
  105. package/security/auth-config.js +43 -0
  106. package/security/create-auth-resources.d.ts +28 -0
  107. package/security/create-auth-resources.js +163 -0
  108. package/security/helper.d.ts +109 -0
  109. package/security/helper.js +298 -0
  110. package/security/resources/api-key/model.d.ts +2 -0
  111. package/security/resources/api-key/model.js +67 -0
  112. package/security/resources/api-key/policy.d.ts +2 -0
  113. package/security/resources/api-key/policy.js +27 -0
  114. package/security/resources/api-key/service.d.ts +3 -0
  115. package/security/resources/api-key/service.js +34 -0
  116. package/security/resources/connected-account/model.d.ts +2 -0
  117. package/security/resources/connected-account/model.js +57 -0
  118. package/security/resources/connected-account/service.d.ts +2 -0
  119. package/security/resources/connected-account/service.js +7 -0
  120. package/security/resources/one-time-token/model.d.ts +2 -0
  121. package/security/resources/one-time-token/model.js +36 -0
  122. package/security/resources/permission/model.d.ts +2 -0
  123. package/security/resources/permission/model.js +16 -0
  124. package/security/resources/role/model.d.ts +2 -0
  125. package/security/resources/role/model.js +22 -0
  126. package/security/store/database-security-store.d.ts +5 -0
  127. package/security/store/database-security-store.js +54 -0
  128. package/seeder/create-seeder.d.ts +29 -0
  129. package/seeder/create-seeder.js +28 -0
  130. package/seeder/index.d.ts +2 -0
  131. package/seeder/index.js +18 -0
  132. package/seeder/resources/seeder/model.d.ts +2 -0
  133. package/seeder/resources/seeder/model.js +38 -0
  134. package/seeder/seeder.d.ts +29 -0
  135. package/seeder/seeder.js +197 -0
  136. package/storage/file-service.d.ts +133 -0
  137. package/storage/file-service.js +586 -0
  138. package/storage/image-config.d.ts +3 -0
  139. package/storage/image-config.js +11 -0
  140. package/storage/resources/file/model.d.ts +2 -0
  141. package/storage/resources/file/model.js +80 -0
  142. package/types/auth.d.ts +23 -0
  143. package/types/auth.js +2 -0
  144. package/types/generated.d.ts +366 -0
  145. package/types/generated.js +3 -0
  146. package/types/storage.d.ts +35 -0
  147. package/types/storage.js +2 -0
  148. package/utils/export-util.d.ts +8 -0
  149. package/utils/export-util.js +26 -0
  150. package/utils/file-util.d.ts +106 -0
  151. package/utils/file-util.js +254 -0
  152. package/utils/model-util.d.ts +36 -0
  153. package/utils/model-util.js +154 -0
  154. package/utils/policy-util.d.ts +18 -0
  155. package/utils/policy-util.js +28 -0
  156. package/utils/virtual-util.d.ts +11 -0
  157. package/utils/virtual-util.js +53 -0
@@ -0,0 +1,14 @@
1
+ /** The placeholder a text search object marks the searched text with. */
2
+ export declare const TEXT_SEARCH_PLACEHOLDER = "{input}";
3
+ /**
4
+ * Builds the database filter of a text search object for the searched text,
5
+ * replacing every placeholder occurrence in its string values (i.e.
6
+ * `'{input}'`) with the text. An `OR` given as an object is turned into the
7
+ * list the database expects, each entry becoming one condition, the way the
8
+ * `_or` operator of a query filter reads it.
9
+ *
10
+ * @param {Object} template The text search object configured on the service.
11
+ * @param {string} input The searched text.
12
+ * @return {Object} A new filter object, the template is left untouched.
13
+ */
14
+ export declare function bindTextSearch(template: any, input: string): any;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEXT_SEARCH_PLACEHOLDER = void 0;
4
+ exports.bindTextSearch = bindTextSearch;
5
+ const common_1 = require("@appweaver/common");
6
+ /** The placeholder a text search object marks the searched text with. */
7
+ exports.TEXT_SEARCH_PLACEHOLDER = '{input}';
8
+ /**
9
+ * Builds the database filter of a text search object for the searched text,
10
+ * replacing every placeholder occurrence in its string values (i.e.
11
+ * `'{input}'`) with the text. An `OR` given as an object is turned into the
12
+ * list the database expects, each entry becoming one condition, the way the
13
+ * `_or` operator of a query filter reads it.
14
+ *
15
+ * @param {Object} template The text search object configured on the service.
16
+ * @param {string} input The searched text.
17
+ * @return {Object} A new filter object, the template is left untouched.
18
+ */
19
+ function bindTextSearch(template, input) {
20
+ if ((0, common_1.isString)(template)) {
21
+ return template.replaceAll(exports.TEXT_SEARCH_PLACEHOLDER, input);
22
+ }
23
+ if ((0, common_1.isArray)(template)) {
24
+ return template.map((item) => bindTextSearch(item, input));
25
+ }
26
+ if (!(0, common_1.isPlainObject)(template)) {
27
+ return template;
28
+ }
29
+ const bound = {};
30
+ for (const [key, value] of Object.entries(template)) {
31
+ bound[key] =
32
+ key === 'OR' && (0, common_1.isPlainObject)(value)
33
+ ? Object.entries(value).map(([field, condition]) => ({
34
+ [field]: bindTextSearch(condition, input)
35
+ }))
36
+ : bindTextSearch(value, input);
37
+ }
38
+ return bound;
39
+ }
package/resources.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { default as apiKey } from './security/resources/api-key/model';
2
+ export { default as connectedAccount } from './security/resources/connected-account/model';
3
+ export { default as oneTimeToken } from './security/resources/one-time-token/model';
4
+ export { default as role } from './security/resources/role/model';
5
+ export { default as permission } from './security/resources/permission/model';
6
+ export { default as seeder } from './seeder/resources/seeder/model';
7
+ export { default as file } from './storage/resources/file/model';
8
+ export { default as apiKeyService } from './security/resources/api-key/service';
9
+ export { default as connectedAccountService } from './security/resources/connected-account/service';
10
+ export { default as apiKeyPolicy } from './security/resources/api-key/policy';
package/resources.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.apiKeyPolicy = exports.connectedAccountService = exports.apiKeyService = exports.file = exports.seeder = exports.permission = exports.role = exports.oneTimeToken = exports.connectedAccount = exports.apiKey = void 0;
7
+ var model_1 = require("./security/resources/api-key/model");
8
+ Object.defineProperty(exports, "apiKey", { enumerable: true, get: function () { return __importDefault(model_1).default; } });
9
+ var model_2 = require("./security/resources/connected-account/model");
10
+ Object.defineProperty(exports, "connectedAccount", { enumerable: true, get: function () { return __importDefault(model_2).default; } });
11
+ var model_3 = require("./security/resources/one-time-token/model");
12
+ Object.defineProperty(exports, "oneTimeToken", { enumerable: true, get: function () { return __importDefault(model_3).default; } });
13
+ var model_4 = require("./security/resources/role/model");
14
+ Object.defineProperty(exports, "role", { enumerable: true, get: function () { return __importDefault(model_4).default; } });
15
+ var model_5 = require("./security/resources/permission/model");
16
+ Object.defineProperty(exports, "permission", { enumerable: true, get: function () { return __importDefault(model_5).default; } });
17
+ var model_6 = require("./seeder/resources/seeder/model");
18
+ Object.defineProperty(exports, "seeder", { enumerable: true, get: function () { return __importDefault(model_6).default; } });
19
+ var model_7 = require("./storage/resources/file/model");
20
+ Object.defineProperty(exports, "file", { enumerable: true, get: function () { return __importDefault(model_7).default; } });
21
+ var service_1 = require("./security/resources/api-key/service");
22
+ Object.defineProperty(exports, "apiKeyService", { enumerable: true, get: function () { return __importDefault(service_1).default; } });
23
+ var service_2 = require("./security/resources/connected-account/service");
24
+ Object.defineProperty(exports, "connectedAccountService", { enumerable: true, get: function () { return __importDefault(service_2).default; } });
25
+ var policy_1 = require("./security/resources/api-key/policy");
26
+ Object.defineProperty(exports, "apiKeyPolicy", { enumerable: true, get: function () { return __importDefault(policy_1).default; } });
@@ -0,0 +1,23 @@
1
+ export declare const passwordConfig: Readonly<{
2
+ ENABLED: boolean;
3
+ MIN_LENGTH: number;
4
+ MAX_LENGTH: number;
5
+ UPPERCASE: boolean;
6
+ LOWERCASE: boolean;
7
+ NUMERIC: boolean;
8
+ SPECIAL: boolean;
9
+ }>;
10
+ export declare const apiKeyConfig: Readonly<{
11
+ MAX_DURATION?: number | undefined;
12
+ ENABLED: boolean;
13
+ KEEP_DATABASE_TABLE: boolean;
14
+ HEADER_NAME: string;
15
+ DELIMITER: string;
16
+ }>;
17
+ export declare const systemConfig: Readonly<{
18
+ ADMIN_INITIAL_PASSWORD?: string | undefined;
19
+ ADMIN_INITIAL_EMAIL: string;
20
+ }>;
21
+ export declare const connectedAccountConfig: Readonly<{
22
+ CONNECTED_ACCOUNTS_KEEP_DATABASE_TABLE: boolean;
23
+ }>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.connectedAccountConfig = exports.systemConfig = exports.apiKeyConfig = exports.passwordConfig = void 0;
4
+ const typebox_1 = require("@sinclair/typebox");
5
+ const common_1 = require("@appweaver/common");
6
+ exports.passwordConfig = (0, common_1.defineConfig)('security.password', {
7
+ /** Enable password-based authentication. Default: `true`. */
8
+ ENABLED: typebox_1.Type.Boolean({ default: true }),
9
+ /** Minimum password length. Default: `8`. */
10
+ MIN_LENGTH: typebox_1.Type.Integer({ default: 8 }),
11
+ /** Maximum password length. Default: `100`. */
12
+ MAX_LENGTH: typebox_1.Type.Integer({ default: 100 }),
13
+ /** Require at least one uppercase letter. Default: `true`. */
14
+ UPPERCASE: typebox_1.Type.Boolean({ default: true }),
15
+ /** Require at least one lowercase letter. Default: `true`. */
16
+ LOWERCASE: typebox_1.Type.Boolean({ default: true }),
17
+ /** Require at least one digit. Default: `true`. */
18
+ NUMERIC: typebox_1.Type.Boolean({ default: true }),
19
+ /** Require at least one special character. Default: `true`. */
20
+ SPECIAL: typebox_1.Type.Boolean({ default: true })
21
+ });
22
+ exports.apiKeyConfig = (0, common_1.defineConfig)('security.apiKey', {
23
+ /** Enable API key authentication. Default: `false`. */
24
+ ENABLED: typebox_1.Type.Boolean({ default: false }),
25
+ /** Keep the API key database table after migrations. Default: `false`. */
26
+ KEEP_DATABASE_TABLE: typebox_1.Type.Boolean({ default: false }),
27
+ /** Request the header name for the API key. Default: `'x-api-key'`. */
28
+ HEADER_NAME: typebox_1.Type.String({ default: 'x-api-key' }),
29
+ /** Maximum API key validity duration in milliseconds. */
30
+ MAX_DURATION: typebox_1.Type.Optional(typebox_1.Type.Integer()),
31
+ /** Prefix delimiter between key ID and secret value. Default: `'AK'`. */
32
+ DELIMITER: typebox_1.Type.String({ default: 'AK' })
33
+ });
34
+ exports.systemConfig = (0, common_1.defineConfig)('system', {
35
+ /** Initial admin account email created on the first run. Default: `'admin@appweaver.co'`. */
36
+ ADMIN_INITIAL_EMAIL: typebox_1.Type.String({ default: 'admin@appweaver.co' }),
37
+ /** Initial admin account password. */
38
+ ADMIN_INITIAL_PASSWORD: typebox_1.Type.Optional(typebox_1.Type.String())
39
+ });
40
+ exports.connectedAccountConfig = (0, common_1.defineConfig)('security.oauth2', {
41
+ /** Keep the `ConnectedAccount` database table even when every OAuth2 provider is disabled. Default: `false`. */
42
+ CONNECTED_ACCOUNTS_KEEP_DATABASE_TABLE: typebox_1.Type.Boolean({ default: false })
43
+ });
@@ -0,0 +1,28 @@
1
+ import { Ctor, IResourceService, ModelName, RegistryType, ResourceModel, ResourceModelConfig, ResourceServiceConfig } from '@appweaver/common';
2
+ import { CheckOAuth2UserFn, RegistrationDataFn, RegistrationFilesFn } from '../types/auth';
3
+ /** The fields an auth model adds to the configured ones. */
4
+ type AuthFieldName = 'email' | 'passwordHash' | 'verifiedEmail' | 'twoFactorAuth' | 'enabled' | 'logoutAt' | 'password' | 'roles' | 'apiKeys';
5
+ /**
6
+ * Creates the resource model of an authenticatable user, adding the email, password, verification, two-factor, and
7
+ * role fields to the configured ones.
8
+ *
9
+ * @param {ResourceModelConfig} modelConfig - The model configuration.
10
+ * @return {ResourceModel} The created auth resource model.
11
+ */
12
+ export declare function createAuthModel<S extends string, R extends string, F extends string, V extends string>(modelConfig: ResourceModelConfig<S, R, F, V, AuthFieldName>): ResourceModel;
13
+ /**
14
+ * Creates the resource service of an authenticatable user, hashing the password on create and update, along with the
15
+ * callbacks preparing the data and files of a registered user. Once the types are generated, the model, create, and
16
+ * update types are inferred from the model name.
17
+ *
18
+ * @param {ResourceServiceConfig} config - The service configuration with the model name, hooks, and registration
19
+ * callbacks.
20
+ * @return {Ctor<IResourceService>} The created service class, defined in the application context.
21
+ */
22
+ export declare function createAuthService<N extends ModelName, T = RegistryType<N, 'model'>, C = RegistryType<N, 'create'>, U = RegistryType<N, 'update'>>(config: ResourceServiceConfig<T, C, U> & {
23
+ modelName: N;
24
+ registrationData?: RegistrationDataFn<C>;
25
+ registrationFiles?: RegistrationFilesFn;
26
+ checkOAuth2User?: CheckOAuth2UserFn;
27
+ }): Ctor<IResourceService<T, T, C, U>>;
28
+ export {};
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuthModel = createAuthModel;
4
+ exports.createAuthService = createAuthService;
5
+ const common_1 = require("@appweaver/common");
6
+ const auth_config_1 = require("./auth-config");
7
+ const helper_1 = require("./helper");
8
+ const create_model_1 = require("../factory/create-model");
9
+ const create_service_1 = require("../factory/create-service");
10
+ /**
11
+ * Creates the resource model of an authenticatable user, adding the email, password, verification, two-factor, and
12
+ * role fields to the configured ones.
13
+ *
14
+ * @param {ResourceModelConfig} modelConfig - The model configuration.
15
+ * @return {ResourceModel} The created auth resource model.
16
+ */
17
+ function createAuthModel(modelConfig) {
18
+ const config = modelConfig;
19
+ const authModelScalars = {
20
+ email: {
21
+ type: 'string',
22
+ unique: true,
23
+ maxLength: 255,
24
+ format: 'email'
25
+ },
26
+ passwordHash: {
27
+ type: 'string',
28
+ required: false,
29
+ hidden: true
30
+ },
31
+ verifiedEmail: {
32
+ type: 'boolean',
33
+ default: false
34
+ },
35
+ twoFactorAuth: {
36
+ type: 'enum',
37
+ values: Object.values(common_1.TwoFactorAuth),
38
+ default: common_1.TwoFactorAuth.None
39
+ },
40
+ enabled: {
41
+ type: 'boolean',
42
+ default: true
43
+ },
44
+ logoutAt: {
45
+ type: 'dateTime',
46
+ required: false
47
+ }
48
+ };
49
+ // Override email properties if already present in the model config
50
+ if (config.scalars?.email?.type === 'string') {
51
+ authModelScalars.email = {
52
+ ...authModelScalars.email,
53
+ ...config.scalars.email
54
+ };
55
+ }
56
+ const authModelVirtual = {
57
+ password: {
58
+ type: 'string',
59
+ required: true,
60
+ input: {
61
+ type: 'all'
62
+ },
63
+ output: {
64
+ type: 'none'
65
+ }
66
+ }
67
+ };
68
+ const authModelRelations = {
69
+ roles: {
70
+ model: 'Role',
71
+ type: 'manyToMany',
72
+ input: {
73
+ type: 'all'
74
+ },
75
+ output: {
76
+ type: 'always',
77
+ include: {
78
+ permissions: {
79
+ type: 'always'
80
+ }
81
+ }
82
+ }
83
+ },
84
+ ...(auth_config_1.apiKeyConfig.ENABLED
85
+ ? {
86
+ apiKeys: {
87
+ model: 'ApiKey',
88
+ type: 'oneToMany',
89
+ mappedBy: (0, common_1.uncapitalize)(config.name),
90
+ input: {
91
+ type: 'none'
92
+ },
93
+ output: {
94
+ type: 'none'
95
+ }
96
+ }
97
+ }
98
+ : {}),
99
+ ...((0, helper_1.isOAuth2Enabled)()
100
+ ? {
101
+ connectedAccounts: {
102
+ model: 'ConnectedAccount',
103
+ type: 'oneToMany',
104
+ mappedBy: (0, common_1.uncapitalize)(config.name),
105
+ input: {
106
+ type: 'none'
107
+ },
108
+ output: {
109
+ type: 'none'
110
+ }
111
+ }
112
+ }
113
+ : {})
114
+ };
115
+ const authModelInputOmit = ['verifiedEmail', 'logoutAt'];
116
+ config.scalars = { ...config.scalars, ...authModelScalars };
117
+ config.virtual = { ...config.virtual, ...authModelVirtual };
118
+ config.relations = { ...config.relations, ...authModelRelations };
119
+ config.create = {
120
+ ...(config.create ?? {}),
121
+ omit: [...(config.create?.omit ?? []), ...authModelInputOmit]
122
+ };
123
+ config.update = {
124
+ ...(config.update ?? {}),
125
+ omit: [...(config.update?.omit ?? []), ...authModelInputOmit]
126
+ };
127
+ const model = (0, create_model_1.createModel)(config);
128
+ model[common_1.RESOURCE_AUTH] = true;
129
+ return model;
130
+ }
131
+ /**
132
+ * Creates the resource service of an authenticatable user, hashing the password on create and update, along with the
133
+ * callbacks preparing the data and files of a registered user. Once the types are generated, the model, create, and
134
+ * update types are inferred from the model name.
135
+ *
136
+ * @param {ResourceServiceConfig} config - The service configuration with the model name, hooks, and registration
137
+ * callbacks.
138
+ * @return {Ctor<IResourceService>} The created service class, defined in the application context.
139
+ */
140
+ function createAuthService(config) {
141
+ // Capture original functions to invoke after new auth logic
142
+ const beforeCreate = config.beforeCreate;
143
+ const beforeUpdate = config.beforeUpdate;
144
+ config.beforeCreate = async (data) => {
145
+ await (0, helper_1.updatePasswordHash)(data, data['password']);
146
+ await beforeCreate?.(data);
147
+ };
148
+ config.beforeUpdate = async (id, data) => {
149
+ await (0, helper_1.updatePasswordHash)(data, data['password'], true);
150
+ await beforeUpdate?.(id, data);
151
+ };
152
+ if (!config.registrationData) {
153
+ config.registrationData = (_, email, password) => {
154
+ return {
155
+ email,
156
+ password
157
+ };
158
+ };
159
+ }
160
+ const service = (0, create_service_1.createService)(config);
161
+ service[common_1.RESOURCE_AUTH] = true;
162
+ return service;
163
+ }
@@ -0,0 +1,109 @@
1
+ import { AuthUser, IResourceService, ResourceModel, ValidationResult } from '@appweaver/common';
2
+ /**
3
+ * Evaluates and retrieves the resource authentication model from the available resource models.
4
+ *
5
+ * The function iterates through the resource models in the given context and returns the first model
6
+ * that satisfies the `isResourceAuthModel` condition. If no such model is found, it returns undefined.
7
+ *
8
+ * @return {ResourceModel | undefined} The resource authentication model if present, otherwise undefined.
9
+ */
10
+ export declare function resourceAuthModel(): ResourceModel | undefined;
11
+ /**
12
+ * Provides authentication service for a resource by identifying and injecting
13
+ * the appropriate resource authentication service if available.
14
+ *
15
+ * @return {IResourceService<AuthUser, AuthUser> | undefined} The resource authentication service
16
+ * instance if found, otherwise undefined.
17
+ */
18
+ export declare function resourceAuthService(): IResourceService<AuthUser, AuthUser> | undefined;
19
+ /**
20
+ * Hashes a plain text password with the Argon2id function of the runtime and a random salt. The hash holds the
21
+ * Argon2 parameters and the salt, in the PHC string format `$argon2id$v=19$m=19456,t=2,p=1$<salt>$<key>`.
22
+ *
23
+ * @param {string} password - The plain text password to be hashed.
24
+ * @return {Promise<string>} A promise that resolves to the hashed password.
25
+ */
26
+ export declare function hashPassword(password: string): Promise<string>;
27
+ /**
28
+ * Validates a plain text password against a hashed password, using the parameters stored in the hash. A hash not in
29
+ * the form {@link hashPassword} produces never matches.
30
+ *
31
+ * @param {string} password - The plain text password to validate.
32
+ * @param {string} passwordHash - The hashed password to compare against.
33
+ * @return {Promise<boolean>} Returns a promise that resolves to `true` if the password matches the hash,
34
+ * otherwise `false`.
35
+ */
36
+ export declare function checkPassword(password: string, passwordHash: string): Promise<boolean>;
37
+ /**
38
+ * Tells whether a password hash was made with other parameters than {@link hashPassword} uses now, so it should be
39
+ * replaced with a new hash of the password, e.g. on the next successful login.
40
+ *
41
+ * @param {string} passwordHash - The stored password hash.
42
+ * @return {boolean} `true` if the hash is not a current Argon2id hash, otherwise `false`.
43
+ */
44
+ export declare function needsRehash(passwordHash: string): boolean;
45
+ /**
46
+ * Updates the password hash for a given user and optionally logs the user out by setting a logout timestamp.
47
+ *
48
+ * @param {Partial<AuthUser>} authUser - The user object containing authentication details. Only partial fields are
49
+ * expected.
50
+ * @param {string} [password] - The new password to hash and set for the user. If not provided, no password update
51
+ * occurs.
52
+ * @param {boolean} [logout=false] - Indicates whether to log the user out by setting the logout timestamp.
53
+ * @return Resolves when the password hash is updated and optional logout processing is complete.
54
+ * @throws {AuthError} `AUTH_PASSWORD_WEAK` if the provided password does not satisfy password complexity requirements.
55
+ */
56
+ export declare function updatePasswordHash(authUser: Partial<AuthUser>, password?: string, logout?: boolean): Promise<void>;
57
+ /**
58
+ * Validates the complexity of a given password based on the configured rules.
59
+ * @param {string} password - The password to be validated.
60
+ * @return {ValidationResult} An object with the validation result and message.
61
+ */
62
+ export declare function validatePasswordComplexity(password: string): ValidationResult;
63
+ /**
64
+ * Checks whether at least one OAuth2 provider is enabled, by resolving each OAuth2 auth source to its
65
+ * `SECURITY_OAUTH2_<PROVIDER>_ENABLED` config flag. New providers are picked up automatically as long as they follow
66
+ * that naming convention.
67
+ *
68
+ * @return {boolean} True when any OAuth2 provider is enabled.
69
+ */
70
+ export declare function isOAuth2Enabled(): boolean;
71
+ /**
72
+ * Checks if the given user has a specific role.
73
+ *
74
+ * @param {AuthUser} authUser - The authenticated user object containing role information.
75
+ * @param {string} role - The name of the role to check for.
76
+ * @return {boolean} True if the user has the specified role; otherwise, false.
77
+ */
78
+ export declare function hasRole(authUser: AuthUser, role: string): boolean;
79
+ /**
80
+ * Checks if the authenticated user has the required roles based on the specified operator.
81
+ *
82
+ * @param {AuthUser} authUser - The authenticated user whose roles are being checked.
83
+ * @param {Array<string> | undefined} roles - The list of roles to check against. If undefined, the method returns
84
+ * true`.
85
+ * @param {'or' | 'and'} [operator='or'] - The logical operator for role matching. Use 'or' to check if the user has at
86
+ * least one role, and 'and' to check if the user has all roles.
87
+ * @return {boolean} Returns `true` if the user satisfies the role check based on the specified operator, otherwise
88
+ * `false`.
89
+ */
90
+ export declare function hasRoles(authUser: AuthUser, roles: Array<string> | undefined, operator?: 'or' | 'and'): boolean;
91
+ /**
92
+ * Determines if the authenticated user has the specified permission.
93
+ *
94
+ * @param {AuthUser} authUser - The authenticated user object containing roles and permissions.
95
+ * @param {string} permission - The name of the permission to check for.
96
+ * @return {boolean} Returns true if the user has the specified permission, otherwise false.
97
+ */
98
+ export declare function hasPermission(authUser: AuthUser, permission: string): boolean;
99
+ /**
100
+ * Checks if the authenticated user has the specified permissions based on the given operator.
101
+ *
102
+ * @param {AuthUser} authUser - The authenticated user object.
103
+ * @param {string[] | undefined} permissions - The list of permissions to check. If undefined, it defaults to granting
104
+ * access.
105
+ * @param {'or' | 'and'} [operator='or'] - Determines whether all permissions (and) or at least one permission (or) must
106
+ * be satisfied.
107
+ * @return {boolean} Returns true if the user satisfies the permission requirements, false otherwise.
108
+ */
109
+ export declare function hasPermissions(authUser: AuthUser, permissions: string[] | undefined, operator?: 'or' | 'and'): boolean;