@appweaver/core 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.
Files changed (271) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +7 -0
  3. package/app/application.d.ts +43 -0
  4. package/app/application.js +112 -0
  5. package/app/create-app.d.ts +32 -0
  6. package/app/create-app.js +38 -0
  7. package/app/index.d.ts +2 -0
  8. package/app/index.js +18 -0
  9. package/app/lifecycle-manager.d.ts +20 -0
  10. package/app/lifecycle-manager.js +42 -0
  11. package/app/load-modules.d.ts +10 -0
  12. package/app/load-modules.js +50 -0
  13. package/app/load-providers.d.ts +8 -0
  14. package/app/load-providers.js +33 -0
  15. package/cache/cache-service.d.ts +72 -0
  16. package/cache/cache-service.js +202 -0
  17. package/cache/cache.d.ts +12 -0
  18. package/cache/cache.js +184 -0
  19. package/cache/caching.d.ts +8 -0
  20. package/cache/caching.js +72 -0
  21. package/cache/eviction/eviction-index.d.ts +35 -0
  22. package/cache/eviction/eviction-index.js +2 -0
  23. package/cache/eviction/fifo-eviction-index.d.ts +7 -0
  24. package/cache/eviction/fifo-eviction-index.js +28 -0
  25. package/cache/eviction/index.d.ts +4 -0
  26. package/cache/eviction/index.js +20 -0
  27. package/cache/eviction/lfu-eviction-index.d.ts +8 -0
  28. package/cache/eviction/lfu-eviction-index.js +82 -0
  29. package/cache/eviction/lru-eviction-index.d.ts +8 -0
  30. package/cache/eviction/lru-eviction-index.js +81 -0
  31. package/cache/index.d.ts +2 -0
  32. package/cache/index.js +18 -0
  33. package/cache/memory-cache.d.ts +4 -0
  34. package/cache/memory-cache.js +12 -0
  35. package/cache/redis-cache.d.ts +4 -0
  36. package/cache/redis-cache.js +12 -0
  37. package/context/context.d.ts +2 -0
  38. package/context/context.js +13 -0
  39. package/context/dependency-injection.d.ts +98 -0
  40. package/context/dependency-injection.js +276 -0
  41. package/context/index.d.ts +2 -0
  42. package/context/index.js +18 -0
  43. package/database/create-client.d.ts +11 -0
  44. package/database/create-client.js +142 -0
  45. package/database/index.d.ts +1 -0
  46. package/database/index.js +17 -0
  47. package/database/prisma-database.d.ts +15 -0
  48. package/database/prisma-database.js +53 -0
  49. package/errors/error-handler.d.ts +3 -0
  50. package/errors/error-handler.js +24 -0
  51. package/errors/error-schema.d.ts +32 -0
  52. package/errors/error-schema.js +31 -0
  53. package/errors/http-error.d.ts +21 -0
  54. package/errors/http-error.js +33 -0
  55. package/errors/index.d.ts +3 -0
  56. package/errors/index.js +19 -0
  57. package/events/node-events.d.ts +7 -0
  58. package/events/node-events.js +39 -0
  59. package/export/export-service.d.ts +19 -0
  60. package/export/export-service.js +154 -0
  61. package/export/index.d.ts +1 -0
  62. package/export/index.js +17 -0
  63. package/factory/create-model.d.ts +2 -0
  64. package/factory/create-model.js +366 -0
  65. package/factory/create-policy.d.ts +2 -0
  66. package/factory/create-policy.js +16 -0
  67. package/factory/create-routes.d.ts +2 -0
  68. package/factory/create-routes.js +21 -0
  69. package/factory/create-service.d.ts +3 -0
  70. package/factory/create-service.js +97 -0
  71. package/factory/index.d.ts +4 -0
  72. package/factory/index.js +20 -0
  73. package/health/health-routes.d.ts +2 -0
  74. package/health/health-routes.js +36 -0
  75. package/health/health-schema.d.ts +45 -0
  76. package/health/health-schema.js +52 -0
  77. package/health/health-service.d.ts +38 -0
  78. package/health/health-service.js +82 -0
  79. package/health/index.d.ts +2 -0
  80. package/health/index.js +18 -0
  81. package/index.d.ts +15 -0
  82. package/index.js +31 -0
  83. package/mailer/email-service.d.ts +36 -0
  84. package/mailer/email-service.js +89 -0
  85. package/mailer/index.d.ts +1 -0
  86. package/mailer/index.js +17 -0
  87. package/mailer/json-mailer.d.ts +7 -0
  88. package/mailer/json-mailer.js +32 -0
  89. package/mailer/smtp-mailer.d.ts +7 -0
  90. package/mailer/smtp-mailer.js +43 -0
  91. package/memory/in-memory.d.ts +24 -0
  92. package/memory/in-memory.js +164 -0
  93. package/memory/redis.d.ts +26 -0
  94. package/memory/redis.js +158 -0
  95. package/package.json +68 -0
  96. package/prisma/client/browser.d.ts +34 -0
  97. package/prisma/client/browser.js +56 -0
  98. package/prisma/client/client.d.ts +53 -0
  99. package/prisma/client/client.js +70 -0
  100. package/prisma/client/commonInputTypes.d.ts +395 -0
  101. package/prisma/client/commonInputTypes.js +11 -0
  102. package/prisma/client/enums.d.ts +1 -0
  103. package/prisma/client/enums.js +11 -0
  104. package/prisma/client/internal/class.d.ts +187 -0
  105. package/prisma/client/internal/class.js +85 -0
  106. package/prisma/client/internal/prismaNamespace.d.ts +987 -0
  107. package/prisma/client/internal/prismaNamespace.js +193 -0
  108. package/prisma/client/internal/prismaNamespaceBrowser.d.ts +125 -0
  109. package/prisma/client/internal/prismaNamespaceBrowser.js +164 -0
  110. package/prisma/client/models/ApiKey.d.ts +1167 -0
  111. package/prisma/client/models/ApiKey.js +2 -0
  112. package/prisma/client/models/File.d.ts +1248 -0
  113. package/prisma/client/models/File.js +2 -0
  114. package/prisma/client/models/OneTimeToken.d.ts +1083 -0
  115. package/prisma/client/models/OneTimeToken.js +2 -0
  116. package/prisma/client/models/Permission.d.ts +1209 -0
  117. package/prisma/client/models/Permission.js +2 -0
  118. package/prisma/client/models/Role.d.ts +1209 -0
  119. package/prisma/client/models/Role.js +2 -0
  120. package/prisma/client/models/Seeder.d.ts +1023 -0
  121. package/prisma/client/models/Seeder.js +2 -0
  122. package/prisma/client/models.d.ts +7 -0
  123. package/prisma/client/models.js +2 -0
  124. package/queue/bull-queue.d.ts +37 -0
  125. package/queue/bull-queue.js +207 -0
  126. package/queue/memory-queue.d.ts +54 -0
  127. package/queue/memory-queue.js +283 -0
  128. package/resource/index.d.ts +4 -0
  129. package/resource/index.js +20 -0
  130. package/resource/resource-loader.d.ts +26 -0
  131. package/resource/resource-loader.js +161 -0
  132. package/resource/resource-routes.d.ts +3 -0
  133. package/resource/resource-routes.js +174 -0
  134. package/resource/resource-schema.d.ts +33 -0
  135. package/resource/resource-schema.js +186 -0
  136. package/resource/resource-service.d.ts +89 -0
  137. package/resource/resource-service.js +772 -0
  138. package/resources.d.ts +9 -0
  139. package/resources.js +24 -0
  140. package/scheduler/cron-scheduler.d.ts +12 -0
  141. package/scheduler/cron-scheduler.js +73 -0
  142. package/security/account/account-routes.d.ts +2 -0
  143. package/security/account/account-routes.js +104 -0
  144. package/security/account/account-schema.d.ts +290 -0
  145. package/security/account/account-schema.js +166 -0
  146. package/security/account/account-service.d.ts +88 -0
  147. package/security/account/account-service.js +218 -0
  148. package/security/account/index.d.ts +3 -0
  149. package/security/account/index.js +19 -0
  150. package/security/api-key/api-key-auth.d.ts +4 -0
  151. package/security/api-key/api-key-auth.js +66 -0
  152. package/security/api-key/index.d.ts +1 -0
  153. package/security/api-key/index.js +17 -0
  154. package/security/auth-routes.d.ts +2 -0
  155. package/security/auth-routes.js +80 -0
  156. package/security/auth-schema.d.ts +215 -0
  157. package/security/auth-schema.js +129 -0
  158. package/security/auth-service.d.ts +117 -0
  159. package/security/auth-service.js +272 -0
  160. package/security/auth.d.ts +3 -0
  161. package/security/auth.js +127 -0
  162. package/security/basic/basic-auth.d.ts +4 -0
  163. package/security/basic/basic-auth.js +32 -0
  164. package/security/basic/index.d.ts +1 -0
  165. package/security/basic/index.js +17 -0
  166. package/security/create-auth-resources.d.ts +6 -0
  167. package/security/create-auth-resources.js +129 -0
  168. package/security/helper.d.ts +127 -0
  169. package/security/helper.js +329 -0
  170. package/security/index.d.ts +4 -0
  171. package/security/index.js +20 -0
  172. package/security/jwt/index.d.ts +2 -0
  173. package/security/jwt/index.js +18 -0
  174. package/security/jwt/jwt-auth.d.ts +4 -0
  175. package/security/jwt/jwt-auth.js +57 -0
  176. package/security/jwt/jwt-keys.d.ts +7 -0
  177. package/security/jwt/jwt-keys.js +43 -0
  178. package/security/oauth2/create-oauth2-plugin.d.ts +17 -0
  179. package/security/oauth2/create-oauth2-plugin.js +85 -0
  180. package/security/oauth2/index.d.ts +3 -0
  181. package/security/oauth2/index.js +19 -0
  182. package/security/oauth2/oauth2-custom.d.ts +7 -0
  183. package/security/oauth2/oauth2-custom.js +40 -0
  184. package/security/oauth2/oauth2-facebook.d.ts +1 -0
  185. package/security/oauth2/oauth2-facebook.js +30 -0
  186. package/security/oauth2/oauth2-google.d.ts +1 -0
  187. package/security/oauth2/oauth2-google.js +28 -0
  188. package/security/oauth2/oauth2-schema.d.ts +10 -0
  189. package/security/oauth2/oauth2-schema.js +53 -0
  190. package/security/recaptcha/index.d.ts +2 -0
  191. package/security/recaptcha/index.js +18 -0
  192. package/security/recaptcha/recaptcha-verify.d.ts +1 -0
  193. package/security/recaptcha/recaptcha-verify.js +33 -0
  194. package/security/recaptcha/recaptcha.d.ts +2 -0
  195. package/security/recaptcha/recaptcha.js +22 -0
  196. package/security/resources/api-key/model.d.ts +2 -0
  197. package/security/resources/api-key/model.js +63 -0
  198. package/security/resources/api-key/policy.d.ts +2 -0
  199. package/security/resources/api-key/policy.js +26 -0
  200. package/security/resources/api-key/routes.d.ts +2 -0
  201. package/security/resources/api-key/routes.js +15 -0
  202. package/security/resources/api-key/service.d.ts +3 -0
  203. package/security/resources/api-key/service.js +33 -0
  204. package/security/resources/one-time-token/model.d.ts +2 -0
  205. package/security/resources/one-time-token/model.js +32 -0
  206. package/security/resources/permission/model.d.ts +2 -0
  207. package/security/resources/permission/model.js +16 -0
  208. package/security/resources/role/model.d.ts +2 -0
  209. package/security/resources/role/model.js +22 -0
  210. package/security/store/database-security-store.d.ts +5 -0
  211. package/security/store/database-security-store.js +51 -0
  212. package/security/store/redis-security-store.d.ts +5 -0
  213. package/security/store/redis-security-store.js +32 -0
  214. package/seeder/create-seeder.d.ts +21 -0
  215. package/seeder/create-seeder.js +17 -0
  216. package/seeder/index.d.ts +2 -0
  217. package/seeder/index.js +18 -0
  218. package/seeder/resources/seeder/model.d.ts +2 -0
  219. package/seeder/resources/seeder/model.js +38 -0
  220. package/seeder/seeder.d.ts +20 -0
  221. package/seeder/seeder.js +175 -0
  222. package/server/create-server.d.ts +20 -0
  223. package/server/create-server.js +160 -0
  224. package/server/index.d.ts +4 -0
  225. package/server/index.js +20 -0
  226. package/server/info-route.d.ts +2 -0
  227. package/server/info-route.js +18 -0
  228. package/server/info-schema.d.ts +37 -0
  229. package/server/info-schema.js +19 -0
  230. package/server/register-model.d.ts +2 -0
  231. package/server/register-model.js +12 -0
  232. package/server/register-plugin.d.ts +2 -0
  233. package/server/register-plugin.js +13 -0
  234. package/server/register-route.d.ts +3 -0
  235. package/server/register-route.js +74 -0
  236. package/server/schemas.d.ts +3 -0
  237. package/server/schemas.js +30 -0
  238. package/server/swagger.d.ts +3 -0
  239. package/server/swagger.js +122 -0
  240. package/storage/file-route.d.ts +2 -0
  241. package/storage/file-route.js +39 -0
  242. package/storage/file-schema.d.ts +9 -0
  243. package/storage/file-schema.js +42 -0
  244. package/storage/file-service.d.ts +81 -0
  245. package/storage/file-service.js +384 -0
  246. package/storage/filesystem-storage.d.ts +10 -0
  247. package/storage/filesystem-storage.js +128 -0
  248. package/storage/index.d.ts +2 -0
  249. package/storage/index.js +18 -0
  250. package/storage/resources/file/model.d.ts +2 -0
  251. package/storage/resources/file/model.js +75 -0
  252. package/types/application-context.d.ts +20 -0
  253. package/types/application-context.js +2 -0
  254. package/types/auth.d.ts +31 -0
  255. package/types/auth.js +2 -0
  256. package/types/fastify-extensions.d.ts +24 -0
  257. package/types/fastify-extensions.js +4 -0
  258. package/types/generated.d.ts +193 -0
  259. package/types/generated.js +3 -0
  260. package/types/index.d.ts +4 -0
  261. package/types/index.js +20 -0
  262. package/types/server.d.ts +4 -0
  263. package/types/server.js +2 -0
  264. package/utils/export-util.d.ts +8 -0
  265. package/utils/export-util.js +25 -0
  266. package/utils/file-util.d.ts +64 -0
  267. package/utils/file-util.js +141 -0
  268. package/utils/index.d.ts +3 -0
  269. package/utils/index.js +19 -0
  270. package/utils/schema-util.d.ts +20 -0
  271. package/utils/schema-util.js +37 -0
@@ -0,0 +1,127 @@
1
+ import { AuthScope, AuthSource, AuthType, 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
+ * Retrieves the currently authenticated user from the request context.
21
+ *
22
+ * @return {AuthUser | null | undefined} The authenticated user object if available,
23
+ * null if no user is authenticated, or undefined if the context does not contain
24
+ * authentication information.
25
+ */
26
+ export declare function currentAuthUser(): AuthUser | null | undefined;
27
+ /**
28
+ * Retrieves the current authentication type from the request context.
29
+ *
30
+ * @return {AuthType | null | undefined} The authentication type if available; otherwise, returns null or undefined.
31
+ */
32
+ export declare function currentAuthType(): AuthType | null | undefined;
33
+ /**
34
+ * Retrieves the current authentication source from the request context.
35
+ *
36
+ * @return {AuthSource | null | undefined} The authentication source if available; otherwise, null or undefined
37
+ * if it is not set.
38
+ */
39
+ export declare function currentAuthSource(): AuthSource | null | undefined;
40
+ /**
41
+ * Hashes a plain text password using a cryptographic salt.
42
+ *
43
+ * @param {string} password - The plain text password to be hashed.
44
+ * @return {Promise<string>} A promise that resolves to the hashed password.
45
+ */
46
+ export declare function hashPassword(password: string): Promise<string>;
47
+ /**
48
+ * Validates a plain text password against a hashed password.
49
+ *
50
+ * @param {string} password - The plain text password to validate.
51
+ * @param {string} passwordHash - The hashed password to compare against.
52
+ * @return {Promise<boolean>} Returns a promise that resolves to `true` if the password matches the hash,
53
+ * otherwise `false`.
54
+ */
55
+ export declare function checkPassword(password: string, passwordHash: string): Promise<boolean>;
56
+ /**
57
+ * Updates the password hash for a given user and optionally logs the user out by setting a logout timestamp.
58
+ *
59
+ * @param {Partial<AuthUser>} authUser - The user object containing authentication details. Only partial fields are
60
+ * expected.
61
+ * @param {string} [password] - The new password to hash and set for the user. If not provided, no password update
62
+ * occurs.
63
+ * @param {boolean} [logout=false] - Indicates whether to log the user out by setting the logout timestamp.
64
+ * @return Resolves when the password hash is updated and optional logout processing is complete.
65
+ * @throws {HttpError} If the provided password does not satisfy password complexity requirements.
66
+ */
67
+ export declare function updatePasswordHash(authUser: Partial<AuthUser>, password?: string, logout?: boolean): Promise<void>;
68
+ /**
69
+ * Validates the complexity of a given password based on the configured rules.
70
+ * @param {string} password - The password to be validated.
71
+ * @return {ValidationResult} An object with the validation result and message.
72
+ */
73
+ export declare function validatePasswordComplexity(password: string): ValidationResult;
74
+ /**
75
+ * Validates a URL and checks if it's allowed based on the configured list of allowed hosts.
76
+ *
77
+ * @param {string} url - The URL string to validate.
78
+ * @return {ValidationResult} An object containing validation result and message.
79
+ */
80
+ export declare function validateRedirectUrl(url: string): ValidationResult;
81
+ /**
82
+ * Checks whether the provided URL is accessible based on the user's JWT payload `scope` property.
83
+ *
84
+ * @param {string} url - The URL path being accessed.
85
+ * @param {AuthScope} authScope - The `scope` property from the decoded JWT payload.
86
+ * @return {boolean} Returns true if the URL is accessible based on the scope; false otherwise.
87
+ */
88
+ export declare function checkScopeAccess(url: string, authScope: AuthScope): boolean;
89
+ /**
90
+ * Checks if the given user has a specific role.
91
+ *
92
+ * @param {AuthUser} authUser - The authenticated user object containing role information.
93
+ * @param {string} role - The name of the role to check for.
94
+ * @return {boolean} True if the user has the specified role; otherwise, false.
95
+ */
96
+ export declare function hasRole(authUser: AuthUser, role: string): boolean;
97
+ /**
98
+ * Checks if the authenticated user has the required roles based on the specified operator.
99
+ *
100
+ * @param {AuthUser} authUser - The authenticated user whose roles are being checked.
101
+ * @param {Array<string> | undefined} roles - The list of roles to check against. If undefined, the method returns
102
+ * true`.
103
+ * @param {'or' | 'and'} [operator='or'] - The logical operator for role matching. Use 'or' to check if the user has at
104
+ * least one role, and 'and' to check if the user has all roles.
105
+ * @return {boolean} Returns `true` if the user satisfies the role check based on the specified operator, otherwise
106
+ * `false`.
107
+ */
108
+ export declare function hasRoles(authUser: AuthUser, roles: Array<string> | undefined, operator?: 'or' | 'and'): boolean;
109
+ /**
110
+ * Determines if the authenticated user has the specified permission.
111
+ *
112
+ * @param {AuthUser} authUser - The authenticated user object containing roles and permissions.
113
+ * @param {string} permission - The name of the permission to check for.
114
+ * @return {boolean} Returns true if the user has the specified permission, otherwise false.
115
+ */
116
+ export declare function hasPermission(authUser: AuthUser, permission: string): boolean;
117
+ /**
118
+ * Checks if the authenticated user has the specified permissions based on the given operator.
119
+ *
120
+ * @param {AuthUser} authUser - The authenticated user object.
121
+ * @param {string[] | undefined} permissions - The list of permissions to check. If undefined, it defaults to granting
122
+ * access.
123
+ * @param {'or' | 'and'} [operator='or'] - Determines whether all permissions (and) or at least one permission (or) must
124
+ * be satisfied.
125
+ * @return {boolean} Returns true if the user satisfies the permission requirements, false otherwise.
126
+ */
127
+ export declare function hasPermissions(authUser: AuthUser, permissions: string[] | undefined, operator?: 'or' | 'and'): boolean;
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resourceAuthModel = resourceAuthModel;
37
+ exports.resourceAuthService = resourceAuthService;
38
+ exports.currentAuthUser = currentAuthUser;
39
+ exports.currentAuthType = currentAuthType;
40
+ exports.currentAuthSource = currentAuthSource;
41
+ exports.hashPassword = hashPassword;
42
+ exports.checkPassword = checkPassword;
43
+ exports.updatePasswordHash = updatePasswordHash;
44
+ exports.validatePasswordComplexity = validatePasswordComplexity;
45
+ exports.validateRedirectUrl = validateRedirectUrl;
46
+ exports.checkScopeAccess = checkScopeAccess;
47
+ exports.hasRole = hasRole;
48
+ exports.hasRoles = hasRoles;
49
+ exports.hasPermission = hasPermission;
50
+ exports.hasPermissions = hasPermissions;
51
+ const bcrypt = __importStar(require("bcrypt"));
52
+ const request_context_1 = require("@fastify/request-context");
53
+ const common_1 = require("@appweaver/common");
54
+ const errors_1 = require("../errors");
55
+ const context_1 = require("../context");
56
+ /**
57
+ * Evaluates and retrieves the resource authentication model from the available resource models.
58
+ *
59
+ * The function iterates through the resource models in the given context and returns the first model
60
+ * that satisfies the `isResourceAuthModel` condition. If no such model is found, it returns undefined.
61
+ *
62
+ * @return {ResourceModel | undefined} The resource authentication model if present, otherwise undefined.
63
+ */
64
+ function resourceAuthModel() {
65
+ for (const model of context_1.context.resource.models.values()) {
66
+ if ((0, common_1.isResourceAuthModel)(model)) {
67
+ return model;
68
+ }
69
+ }
70
+ }
71
+ /**
72
+ * Provides authentication service for a resource by identifying and injecting
73
+ * the appropriate resource authentication service if available.
74
+ *
75
+ * @return {IResourceService<AuthUser, AuthUser> | undefined} The resource authentication service
76
+ * instance if found, otherwise undefined.
77
+ */
78
+ function resourceAuthService() {
79
+ for (const service of context_1.context.resource.services.values()) {
80
+ if ((0, common_1.isResourceAuthService)(service)) {
81
+ return (0, context_1.injectService)(service[common_1.RESOURCE_NAME]);
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Retrieves the currently authenticated user from the request context.
87
+ *
88
+ * @return {AuthUser | null | undefined} The authenticated user object if available,
89
+ * null if no user is authenticated, or undefined if the context does not contain
90
+ * authentication information.
91
+ */
92
+ function currentAuthUser() {
93
+ return request_context_1.requestContext.get('authUser');
94
+ }
95
+ /**
96
+ * Retrieves the current authentication type from the request context.
97
+ *
98
+ * @return {AuthType | null | undefined} The authentication type if available; otherwise, returns null or undefined.
99
+ */
100
+ function currentAuthType() {
101
+ return request_context_1.requestContext.get('authType');
102
+ }
103
+ /**
104
+ * Retrieves the current authentication source from the request context.
105
+ *
106
+ * @return {AuthSource | null | undefined} The authentication source if available; otherwise, null or undefined
107
+ * if it is not set.
108
+ */
109
+ function currentAuthSource() {
110
+ return request_context_1.requestContext.get('authSource');
111
+ }
112
+ /**
113
+ * Hashes a plain text password using a cryptographic salt.
114
+ *
115
+ * @param {string} password - The plain text password to be hashed.
116
+ * @return {Promise<string>} A promise that resolves to the hashed password.
117
+ */
118
+ async function hashPassword(password) {
119
+ const salt = await bcrypt.genSalt();
120
+ return bcrypt.hash(password, salt);
121
+ }
122
+ /**
123
+ * Validates a plain text password against a hashed password.
124
+ *
125
+ * @param {string} password - The plain text password to validate.
126
+ * @param {string} passwordHash - The hashed password to compare against.
127
+ * @return {Promise<boolean>} Returns a promise that resolves to `true` if the password matches the hash,
128
+ * otherwise `false`.
129
+ */
130
+ async function checkPassword(password, passwordHash) {
131
+ return bcrypt.compare(password, passwordHash);
132
+ }
133
+ /**
134
+ * Updates the password hash for a given user and optionally logs the user out by setting a logout timestamp.
135
+ *
136
+ * @param {Partial<AuthUser>} authUser - The user object containing authentication details. Only partial fields are
137
+ * expected.
138
+ * @param {string} [password] - The new password to hash and set for the user. If not provided, no password update
139
+ * occurs.
140
+ * @param {boolean} [logout=false] - Indicates whether to log the user out by setting the logout timestamp.
141
+ * @return Resolves when the password hash is updated and optional logout processing is complete.
142
+ * @throws {HttpError} If the provided password does not satisfy password complexity requirements.
143
+ */
144
+ async function updatePasswordHash(authUser, password, logout = false) {
145
+ if (password) {
146
+ if (!common_1.config.SECURITY_PASSWORD_ENABLED) {
147
+ throw new errors_1.HttpError('Password creation is not supported', 403);
148
+ }
149
+ const result = validatePasswordComplexity(password);
150
+ if (!result.valid) {
151
+ throw new errors_1.HttpError(result.message, 400);
152
+ }
153
+ authUser.passwordHash = await hashPassword(password);
154
+ if (logout) {
155
+ authUser.logoutAt = new Date();
156
+ }
157
+ }
158
+ delete authUser['password'];
159
+ }
160
+ /**
161
+ * Validates the complexity of a given password based on the configured rules.
162
+ * @param {string} password - The password to be validated.
163
+ * @return {ValidationResult} An object with the validation result and message.
164
+ */
165
+ function validatePasswordComplexity(password) {
166
+ const minLength = common_1.config.SECURITY_PASSWORD_MIN_LENGTH;
167
+ if (password.length < minLength) {
168
+ return {
169
+ valid: false,
170
+ message: `Password must be at least ${minLength} characters long`
171
+ };
172
+ }
173
+ const maxLength = common_1.config.SECURITY_PASSWORD_MAX_LENGTH;
174
+ if (password.length > maxLength) {
175
+ return {
176
+ valid: false,
177
+ message: `Password must not be longer than ${maxLength} characters`
178
+ };
179
+ }
180
+ if (!/[A-Z]/.test(password) && common_1.config.SECURITY_PASSWORD_UPPERCASE) {
181
+ return {
182
+ valid: false,
183
+ message: `Password must have at least one uppercase character`
184
+ };
185
+ }
186
+ if (!/[a-z]/.test(password) && common_1.config.SECURITY_PASSWORD_LOWERCASE) {
187
+ return {
188
+ valid: false,
189
+ message: `Password must have at least one lowercase character`
190
+ };
191
+ }
192
+ if (!/[0-9]/.test(password) && common_1.config.SECURITY_PASSWORD_NUMERIC) {
193
+ return {
194
+ valid: false,
195
+ message: `Password must have at least one numeric character`
196
+ };
197
+ }
198
+ if (!/[^A-Za-z0-9]/.test(password) && common_1.config.SECURITY_PASSWORD_SPECIAL) {
199
+ return {
200
+ valid: false,
201
+ message: `Password must have at least one special character`
202
+ };
203
+ }
204
+ return { valid: true, message: 'OK' };
205
+ }
206
+ /**
207
+ * Validates a URL and checks if it's allowed based on the configured list of allowed hosts.
208
+ *
209
+ * @param {string} url - The URL string to validate.
210
+ * @return {ValidationResult} An object containing validation result and message.
211
+ */
212
+ function validateRedirectUrl(url) {
213
+ try {
214
+ new URL(url);
215
+ }
216
+ catch (e) {
217
+ return {
218
+ valid: false,
219
+ message: `Invalid URL format: ${url}`
220
+ };
221
+ }
222
+ const checkUrl = new URL(url);
223
+ const allowedHosts = common_1.config.SECURITY_ALLOWED_REDIRECT_HOSTS;
224
+ if (!allowedHosts.includes('*') &&
225
+ !allowedHosts.includes(checkUrl.hostname)) {
226
+ return {
227
+ valid: false,
228
+ message: `The URL hostname '${checkUrl.hostname}' is not allowed`
229
+ };
230
+ }
231
+ return {
232
+ valid: true,
233
+ message: 'URL is valid and allowed'
234
+ };
235
+ }
236
+ /**
237
+ * Checks whether the provided URL is accessible based on the user's JWT payload `scope` property.
238
+ *
239
+ * @param {string} url - The URL path being accessed.
240
+ * @param {AuthScope} authScope - The `scope` property from the decoded JWT payload.
241
+ * @return {boolean} Returns true if the URL is accessible based on the scope; false otherwise.
242
+ */
243
+ function checkScopeAccess(url, authScope) {
244
+ const securityPrefix = common_1.config.SECURITY_ROUTE_PREFIX.replace(/\/$/, '');
245
+ const accountPrefix = common_1.config.SECURITY_ACCOUNT_ROUTE_PREFIX.replace(/\/$/, '');
246
+ const refreshPath = `${securityPrefix}/refresh`;
247
+ const twoFASendPath = `${accountPrefix}/2fa-send-code`;
248
+ const twoFAVerifyPath = `${accountPrefix}/verify-2fa-code`;
249
+ const scopeConfigs = [
250
+ {
251
+ scope: common_1.AuthScope.Auth,
252
+ disallowedPaths: [refreshPath, twoFASendPath, twoFAVerifyPath]
253
+ },
254
+ {
255
+ scope: common_1.AuthScope.Refresh,
256
+ allowedPaths: [refreshPath]
257
+ },
258
+ {
259
+ scope: common_1.AuthScope.TwoFA,
260
+ allowedPaths: [twoFASendPath, twoFAVerifyPath]
261
+ }
262
+ ];
263
+ const scopeConfig = scopeConfigs.find(({ scope }) => scope === authScope);
264
+ if (!scopeConfig) {
265
+ return false;
266
+ }
267
+ const { allowedPaths, disallowedPaths } = scopeConfig;
268
+ return ((allowedPaths !== undefined && allowedPaths.includes(url)) ||
269
+ (disallowedPaths !== undefined && !disallowedPaths.includes(url)));
270
+ }
271
+ /**
272
+ * Checks if the given user has a specific role.
273
+ *
274
+ * @param {AuthUser} authUser - The authenticated user object containing role information.
275
+ * @param {string} role - The name of the role to check for.
276
+ * @return {boolean} True if the user has the specified role; otherwise, false.
277
+ */
278
+ function hasRole(authUser, role) {
279
+ return authUser.roles.some((r) => r.name === role);
280
+ }
281
+ /**
282
+ * Checks if the authenticated user has the required roles based on the specified operator.
283
+ *
284
+ * @param {AuthUser} authUser - The authenticated user whose roles are being checked.
285
+ * @param {Array<string> | undefined} roles - The list of roles to check against. If undefined, the method returns
286
+ * true`.
287
+ * @param {'or' | 'and'} [operator='or'] - The logical operator for role matching. Use 'or' to check if the user has at
288
+ * least one role, and 'and' to check if the user has all roles.
289
+ * @return {boolean} Returns `true` if the user satisfies the role check based on the specified operator, otherwise
290
+ * `false`.
291
+ */
292
+ function hasRoles(authUser, roles, operator = 'or') {
293
+ if (!roles) {
294
+ return true;
295
+ }
296
+ const predicate = (role) => hasRole(authUser, role);
297
+ return operator === 'and' ? roles.every(predicate) : roles.some(predicate);
298
+ }
299
+ /**
300
+ * Determines if the authenticated user has the specified permission.
301
+ *
302
+ * @param {AuthUser} authUser - The authenticated user object containing roles and permissions.
303
+ * @param {string} permission - The name of the permission to check for.
304
+ * @return {boolean} Returns true if the user has the specified permission, otherwise false.
305
+ */
306
+ function hasPermission(authUser, permission) {
307
+ return authUser.roles
308
+ .flatMap((r) => r.permissions)
309
+ .some((p) => p.name === permission);
310
+ }
311
+ /**
312
+ * Checks if the authenticated user has the specified permissions based on the given operator.
313
+ *
314
+ * @param {AuthUser} authUser - The authenticated user object.
315
+ * @param {string[] | undefined} permissions - The list of permissions to check. If undefined, it defaults to granting
316
+ * access.
317
+ * @param {'or' | 'and'} [operator='or'] - Determines whether all permissions (and) or at least one permission (or) must
318
+ * be satisfied.
319
+ * @return {boolean} Returns true if the user satisfies the permission requirements, false otherwise.
320
+ */
321
+ function hasPermissions(authUser, permissions, operator = 'or') {
322
+ if (!permissions) {
323
+ return true;
324
+ }
325
+ const predicate = (perm) => hasPermission(authUser, perm);
326
+ return operator === 'and'
327
+ ? permissions.every(predicate)
328
+ : permissions.some(predicate);
329
+ }
@@ -0,0 +1,4 @@
1
+ export * from './oauth2/create-oauth2-plugin';
2
+ export * from './auth-service';
3
+ export * from './auth-schema';
4
+ export * from './helper';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./oauth2/create-oauth2-plugin"), exports);
18
+ __exportStar(require("./auth-service"), exports);
19
+ __exportStar(require("./auth-schema"), exports);
20
+ __exportStar(require("./helper"), exports);
@@ -0,0 +1,2 @@
1
+ export * from './jwt-auth';
2
+ export * from './jwt-keys';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./jwt-auth"), exports);
18
+ __exportStar(require("./jwt-keys"), exports);
@@ -0,0 +1,4 @@
1
+ import { FastifyRequest } from 'fastify';
2
+ import { Server } from '../../types';
3
+ export declare const jwtAuth: (server: Server) => Promise<void>;
4
+ export declare function hasBearerAuth(request: FastifyRequest): boolean;
@@ -0,0 +1,57 @@
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.jwtAuth = void 0;
7
+ exports.hasBearerAuth = hasBearerAuth;
8
+ const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
9
+ const jwt_1 = __importDefault(require("@fastify/jwt"));
10
+ const request_context_1 = require("@fastify/request-context");
11
+ const common_1 = require("@appweaver/common");
12
+ const context_1 = require("../../context");
13
+ const auth_service_1 = require("../auth-service");
14
+ const errors_1 = require("../../errors");
15
+ const jwt_keys_1 = require("./jwt-keys");
16
+ exports.jwtAuth = (0, fastify_plugin_1.default)(async (server) => {
17
+ const authService = (0, context_1.inject)(auth_service_1.AuthService);
18
+ if (common_1.config.SECURITY_JWT_SECRET) {
19
+ server.register(jwt_1.default, {
20
+ secret: common_1.config.SECURITY_JWT_SECRET
21
+ });
22
+ }
23
+ else {
24
+ const { keysExisted, publicKey, privateKey } = await (0, jwt_keys_1.loadSecurityKeys)(common_1.config.SECURITY_JWT_PUBLIC_KEY_PATH, common_1.config.SECURITY_JWT_PRIVATE_KEY_PATH, common_1.config.SECURITY_JWT_AUTO_GENERATE_KEYS);
25
+ if (!keysExisted) {
26
+ common_1.logger.info({
27
+ publicKeyPath: common_1.config.SECURITY_JWT_PUBLIC_KEY_PATH,
28
+ privateKeyPath: common_1.config.SECURITY_JWT_PRIVATE_KEY_PATH
29
+ }, 'Security keys generated');
30
+ }
31
+ server.register(jwt_1.default, {
32
+ secret: {
33
+ public: publicKey,
34
+ private: privateKey
35
+ },
36
+ sign: { algorithm: 'RS256' }
37
+ });
38
+ }
39
+ server.decorate('authenticateJWT', async (request) => {
40
+ let payload;
41
+ let authUser;
42
+ try {
43
+ payload = await request.jwtVerify();
44
+ authUser = await authService.findById(payload.sub);
45
+ }
46
+ catch (e) {
47
+ throw new errors_1.HttpError('Authentication error', 401, e);
48
+ }
49
+ authService.authorize(authUser, request.url, request.routeOptions.config, payload);
50
+ request_context_1.requestContext.set('authUser', authUser);
51
+ request_context_1.requestContext.set('authType', common_1.AuthType.Jwt);
52
+ request_context_1.requestContext.set('authSource', payload.source);
53
+ });
54
+ });
55
+ function hasBearerAuth(request) {
56
+ return (request.headers.authorization?.toLowerCase().startsWith('bearer') === true);
57
+ }
@@ -0,0 +1,7 @@
1
+ export declare function ensureSecurityKeys(publicKeyPath: string, privateKeyPath: string, generateIfNotExists: boolean): Promise<boolean>;
2
+ export declare function generateSecurityKeys(publicKeyPath: string, privateKeyPath: string): Promise<void>;
3
+ export declare function loadSecurityKeys(publicKeyPath: string, privateKeyPath: string, generateIfNotExists: boolean): Promise<{
4
+ keysExisted: boolean;
5
+ publicKey: string;
6
+ privateKey: string;
7
+ }>;
@@ -0,0 +1,43 @@
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.ensureSecurityKeys = ensureSecurityKeys;
7
+ exports.generateSecurityKeys = generateSecurityKeys;
8
+ exports.loadSecurityKeys = loadSecurityKeys;
9
+ const promises_1 = __importDefault(require("node:fs/promises"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_util_1 = require("node:util");
12
+ const node_crypto_1 = require("node:crypto");
13
+ async function ensureSecurityKeys(publicKeyPath, privateKeyPath, generateIfNotExists) {
14
+ try {
15
+ await promises_1.default.access(publicKeyPath, promises_1.default.constants.F_OK);
16
+ await promises_1.default.access(privateKeyPath, promises_1.default.constants.F_OK);
17
+ return true;
18
+ }
19
+ catch (e) {
20
+ if (!generateIfNotExists) {
21
+ throw e;
22
+ }
23
+ await generateSecurityKeys(publicKeyPath, privateKeyPath);
24
+ return false;
25
+ }
26
+ }
27
+ async function generateSecurityKeys(publicKeyPath, privateKeyPath) {
28
+ const { privateKey, publicKey } = await (0, node_util_1.promisify)(node_crypto_1.generateKeyPair)('rsa', {
29
+ modulusLength: 2048,
30
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
31
+ privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
32
+ });
33
+ await promises_1.default.mkdir(node_path_1.default.dirname(publicKeyPath), { recursive: true });
34
+ await promises_1.default.writeFile(publicKeyPath, publicKey, 'utf8');
35
+ await promises_1.default.mkdir(node_path_1.default.dirname(privateKeyPath), { recursive: true });
36
+ await promises_1.default.writeFile(privateKeyPath, privateKey, 'utf8');
37
+ }
38
+ async function loadSecurityKeys(publicKeyPath, privateKeyPath, generateIfNotExists) {
39
+ const keysExisted = await ensureSecurityKeys(publicKeyPath, privateKeyPath, generateIfNotExists);
40
+ const publicKey = await promises_1.default.readFile(publicKeyPath, 'utf8');
41
+ const privateKey = await promises_1.default.readFile(privateKeyPath, 'utf8');
42
+ return { keysExisted, publicKey, privateKey };
43
+ }
@@ -0,0 +1,17 @@
1
+ import { AuthSource } from '@appweaver/common';
2
+ import { Server } from '../../types';
3
+ export type UserInfo = {
4
+ id: string;
5
+ email: string;
6
+ firstName: string;
7
+ lastName: string;
8
+ };
9
+ export type OAuth2Config = {
10
+ enabled: boolean;
11
+ clientId?: string;
12
+ clientSecret?: string;
13
+ issuer?: string;
14
+ scope: string[];
15
+ extractUserInfo: (accessToken: string) => Promise<UserInfo>;
16
+ };
17
+ export declare function createOAuth2Plugin(authSource: AuthSource, oAuth2Config: OAuth2Config): (server: Server) => Promise<void>;