@webda/core 2.0.0-beta.1 → 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 (279) hide show
  1. package/lib/application.d.ts +9 -21
  2. package/lib/application.js +71 -84
  3. package/lib/application.js.map +1 -1
  4. package/lib/application.spec.js +121 -140
  5. package/lib/application.spec.js.map +1 -1
  6. package/lib/core.d.ts +86 -46
  7. package/lib/core.js +254 -316
  8. package/lib/core.js.map +1 -1
  9. package/lib/core.spec.js +326 -391
  10. package/lib/core.spec.js.map +1 -1
  11. package/lib/index.d.ts +49 -45
  12. package/lib/index.js +54 -67
  13. package/lib/index.js.map +1 -1
  14. package/lib/models/aclmodel.d.ts +2 -2
  15. package/lib/models/aclmodel.js +63 -90
  16. package/lib/models/aclmodel.js.map +1 -1
  17. package/lib/models/aclmodel.spec.js +127 -151
  18. package/lib/models/aclmodel.spec.js.map +1 -1
  19. package/lib/models/coremodel.d.ts +84 -11
  20. package/lib/models/coremodel.js +104 -103
  21. package/lib/models/coremodel.js.map +1 -1
  22. package/lib/models/coremodel.spec.js +91 -91
  23. package/lib/models/coremodel.spec.js.map +1 -1
  24. package/lib/models/deployment.js +1 -2
  25. package/lib/models/ident.d.ts +5 -3
  26. package/lib/models/ident.js +4 -9
  27. package/lib/models/ident.js.map +1 -1
  28. package/lib/models/ident.spec.js +9 -11
  29. package/lib/models/ident.spec.js.map +1 -1
  30. package/lib/models/ownermodel.d.ts +12 -2
  31. package/lib/models/ownermodel.js +54 -62
  32. package/lib/models/ownermodel.js.map +1 -1
  33. package/lib/models/ownermodel.spec.js +129 -152
  34. package/lib/models/ownermodel.spec.js.map +1 -1
  35. package/lib/models/rolemodel.d.ts +2 -2
  36. package/lib/models/rolemodel.js +24 -40
  37. package/lib/models/rolemodel.js.map +1 -1
  38. package/lib/models/rolemodel.spec.js +44 -61
  39. package/lib/models/rolemodel.spec.js.map +1 -1
  40. package/lib/models/user.d.ts +5 -5
  41. package/lib/models/user.js +3 -8
  42. package/lib/models/user.js.map +1 -1
  43. package/lib/models/user.spec.js +14 -16
  44. package/lib/models/user.spec.js.map +1 -1
  45. package/lib/queues/filequeue.d.ts +2 -2
  46. package/lib/queues/filequeue.js +72 -93
  47. package/lib/queues/filequeue.js.map +1 -1
  48. package/lib/queues/filequeue.spec.js +53 -70
  49. package/lib/queues/filequeue.spec.js.map +1 -1
  50. package/lib/queues/memoryqueue.d.ts +2 -2
  51. package/lib/queues/memoryqueue.js +37 -61
  52. package/lib/queues/memoryqueue.js.map +1 -1
  53. package/lib/queues/memoryqueue.spec.js +142 -165
  54. package/lib/queues/memoryqueue.spec.js.map +1 -1
  55. package/lib/queues/pubsubservice.d.ts +2 -2
  56. package/lib/queues/pubsubservice.js +3 -7
  57. package/lib/queues/pubsubservice.js.map +1 -1
  58. package/lib/queues/queue.spec.d.ts +1 -1
  59. package/lib/queues/queue.spec.js +42 -56
  60. package/lib/queues/queue.spec.js.map +1 -1
  61. package/lib/queues/queueservice.d.ts +4 -4
  62. package/lib/queues/queueservice.js +52 -67
  63. package/lib/queues/queueservice.js.map +1 -1
  64. package/lib/router.d.ts +7 -3
  65. package/lib/router.js +49 -48
  66. package/lib/router.js.map +1 -1
  67. package/lib/router.spec.js +64 -61
  68. package/lib/router.spec.js.map +1 -1
  69. package/lib/services/asyncevents.d.ts +2 -2
  70. package/lib/services/asyncevents.js +44 -64
  71. package/lib/services/asyncevents.js.map +1 -1
  72. package/lib/services/asyncevents.spec.js +81 -98
  73. package/lib/services/asyncevents.spec.js.map +1 -1
  74. package/lib/services/authentication.d.ts +28 -19
  75. package/lib/services/authentication.js +539 -571
  76. package/lib/services/authentication.js.map +1 -1
  77. package/lib/services/authentication.spec.js +411 -447
  78. package/lib/services/authentication.spec.js.map +1 -1
  79. package/lib/services/binary.d.ts +8 -6
  80. package/lib/services/binary.js +212 -244
  81. package/lib/services/binary.js.map +1 -1
  82. package/lib/services/binary.spec.d.ts +3 -3
  83. package/lib/services/binary.spec.js +390 -443
  84. package/lib/services/binary.spec.js.map +1 -1
  85. package/lib/services/cloudbinary.d.ts +3 -3
  86. package/lib/services/cloudbinary.js +46 -71
  87. package/lib/services/cloudbinary.js.map +1 -1
  88. package/lib/services/cloudbinary.spec.d.ts +3 -3
  89. package/lib/services/cloudbinary.spec.js +133 -162
  90. package/lib/services/cloudbinary.spec.js.map +1 -1
  91. package/lib/services/configuration.d.ts +6 -3
  92. package/lib/services/configuration.js +78 -103
  93. package/lib/services/configuration.js.map +1 -1
  94. package/lib/services/configuration.spec.js +63 -83
  95. package/lib/services/configuration.spec.js.map +1 -1
  96. package/lib/services/cron.d.ts +3 -2
  97. package/lib/services/cron.js +9 -13
  98. package/lib/services/cron.js.map +1 -1
  99. package/lib/services/cron.spec.js +18 -21
  100. package/lib/services/cron.spec.js.map +1 -1
  101. package/lib/services/cryptoservice.d.ts +258 -0
  102. package/lib/services/cryptoservice.js +312 -0
  103. package/lib/services/cryptoservice.js.map +1 -0
  104. package/lib/services/cryptoservice.spec.d.ts +1 -0
  105. package/lib/services/cryptoservice.spec.js +137 -0
  106. package/lib/services/cryptoservice.spec.js.map +1 -0
  107. package/lib/services/debugmailer.d.ts +1 -1
  108. package/lib/services/debugmailer.js +13 -34
  109. package/lib/services/debugmailer.js.map +1 -1
  110. package/lib/services/debugmailer.spec.js +16 -29
  111. package/lib/services/debugmailer.spec.js.map +1 -1
  112. package/lib/services/echo.d.ts +2 -2
  113. package/lib/services/echo.js +15 -31
  114. package/lib/services/echo.js.map +1 -1
  115. package/lib/services/echo.spec.js +27 -40
  116. package/lib/services/echo.spec.js.map +1 -1
  117. package/lib/services/filebinary.d.ts +15 -5
  118. package/lib/services/filebinary.js +171 -200
  119. package/lib/services/filebinary.js.map +1 -1
  120. package/lib/services/filebinary.spec.d.ts +2 -1
  121. package/lib/services/filebinary.spec.js +106 -117
  122. package/lib/services/filebinary.spec.js.map +1 -1
  123. package/lib/services/fileconfiguration.d.ts +2 -2
  124. package/lib/services/fileconfiguration.js +25 -43
  125. package/lib/services/fileconfiguration.js.map +1 -1
  126. package/lib/services/fileconfiguration.spec.js +79 -109
  127. package/lib/services/fileconfiguration.spec.js.map +1 -1
  128. package/lib/services/invitationservice.d.ts +9 -9
  129. package/lib/services/invitationservice.js +275 -313
  130. package/lib/services/invitationservice.js.map +1 -1
  131. package/lib/services/invitationservice.spec.js +442 -448
  132. package/lib/services/invitationservice.spec.js.map +1 -1
  133. package/lib/services/kubernetesconfiguration.d.ts +2 -2
  134. package/lib/services/kubernetesconfiguration.js +41 -59
  135. package/lib/services/kubernetesconfiguration.js.map +1 -1
  136. package/lib/services/kubernetesconfiguration.spec.js +80 -98
  137. package/lib/services/kubernetesconfiguration.spec.js.map +1 -1
  138. package/lib/services/mailer.d.ts +4 -4
  139. package/lib/services/mailer.js +62 -86
  140. package/lib/services/mailer.js.map +1 -1
  141. package/lib/services/mailer.spec.js +86 -127
  142. package/lib/services/mailer.spec.js.map +1 -1
  143. package/lib/services/notificationservice.d.ts +4 -4
  144. package/lib/services/notificationservice.js +23 -42
  145. package/lib/services/notificationservice.js.map +1 -1
  146. package/lib/services/notificationservice.spec.js +47 -73
  147. package/lib/services/notificationservice.spec.js.map +1 -1
  148. package/lib/services/oauth.d.ts +32 -6
  149. package/lib/services/oauth.js +73 -78
  150. package/lib/services/oauth.js.map +1 -1
  151. package/lib/services/oauth.spec.js +128 -147
  152. package/lib/services/oauth.spec.js.map +1 -1
  153. package/lib/services/proxy.d.ts +74 -0
  154. package/lib/services/proxy.js +126 -0
  155. package/lib/services/proxy.js.map +1 -0
  156. package/lib/services/proxy.spec.d.ts +1 -0
  157. package/lib/services/proxy.spec.js +59 -0
  158. package/lib/services/proxy.spec.js.map +1 -0
  159. package/lib/services/resource.d.ts +2 -2
  160. package/lib/services/resource.js +12 -18
  161. package/lib/services/resource.js.map +1 -1
  162. package/lib/services/resource.spec.js +67 -99
  163. package/lib/services/resource.spec.js.map +1 -1
  164. package/lib/services/service.d.ts +33 -7
  165. package/lib/services/service.js +74 -42
  166. package/lib/services/service.js.map +1 -1
  167. package/lib/services/service.spec.js +62 -67
  168. package/lib/services/service.spec.js.map +1 -1
  169. package/lib/services/version.d.ts +1 -1
  170. package/lib/services/version.js +3 -8
  171. package/lib/services/version.js.map +1 -1
  172. package/lib/services/version.spec.js +11 -24
  173. package/lib/services/version.spec.js.map +1 -1
  174. package/lib/stores/aggregator.d.ts +3 -3
  175. package/lib/stores/aggregator.js +37 -57
  176. package/lib/stores/aggregator.js.map +1 -1
  177. package/lib/stores/file.d.ts +3 -3
  178. package/lib/stores/file.js +93 -131
  179. package/lib/stores/file.js.map +1 -1
  180. package/lib/stores/file.spec.d.ts +2 -2
  181. package/lib/stores/file.spec.js +261 -289
  182. package/lib/stores/file.spec.js.map +1 -1
  183. package/lib/stores/mapper.d.ts +4 -4
  184. package/lib/stores/mapper.js +112 -137
  185. package/lib/stores/mapper.js.map +1 -1
  186. package/lib/stores/mapper.spec.js +131 -150
  187. package/lib/stores/mapper.spec.js.map +1 -1
  188. package/lib/stores/memory.d.ts +67 -6
  189. package/lib/stores/memory.js +155 -117
  190. package/lib/stores/memory.js.map +1 -1
  191. package/lib/stores/memory.spec.d.ts +3 -2
  192. package/lib/stores/memory.spec.js +127 -105
  193. package/lib/stores/memory.spec.js.map +1 -1
  194. package/lib/stores/store.d.ts +35 -15
  195. package/lib/stores/store.js +839 -821
  196. package/lib/stores/store.js.map +1 -1
  197. package/lib/stores/store.spec.d.ts +6 -4
  198. package/lib/stores/store.spec.js +627 -647
  199. package/lib/stores/store.spec.js.map +1 -1
  200. package/lib/stores/webdaql/WebdaQLLexer.d.ts +4 -4
  201. package/lib/stores/webdaql/WebdaQLLexer.js +9 -13
  202. package/lib/stores/webdaql/WebdaQLLexer.js.map +1 -1
  203. package/lib/stores/webdaql/WebdaQLParserLexer.d.ts +4 -4
  204. package/lib/stores/webdaql/WebdaQLParserLexer.js +9 -13
  205. package/lib/stores/webdaql/WebdaQLParserLexer.js.map +1 -1
  206. package/lib/stores/webdaql/WebdaQLParserListener.d.ts +2 -2
  207. package/lib/stores/webdaql/WebdaQLParserListener.js +1 -2
  208. package/lib/stores/webdaql/WebdaQLParserListener.js.map +1 -1
  209. package/lib/stores/webdaql/WebdaQLParserParser.d.ts +10 -10
  210. package/lib/stores/webdaql/WebdaQLParserParser.js +62 -91
  211. package/lib/stores/webdaql/WebdaQLParserParser.js.map +1 -1
  212. package/lib/stores/webdaql/WebdaQLParserVisitor.d.ts +2 -2
  213. package/lib/stores/webdaql/WebdaQLParserVisitor.js +1 -2
  214. package/lib/stores/webdaql/WebdaQLParserVisitor.js.map +1 -1
  215. package/lib/stores/webdaql/query.d.ts +4 -5
  216. package/lib/stores/webdaql/query.js +16 -19
  217. package/lib/stores/webdaql/query.js.map +1 -1
  218. package/lib/stores/webdaql/query.spec.js +30 -32
  219. package/lib/stores/webdaql/query.spec.js.map +1 -1
  220. package/lib/test.d.ts +3 -3
  221. package/lib/test.js +74 -94
  222. package/lib/test.js.map +1 -1
  223. package/lib/unpackedapplication.d.ts +1 -1
  224. package/lib/unpackedapplication.js +25 -31
  225. package/lib/unpackedapplication.js.map +1 -1
  226. package/lib/utils/abstractdeployer.js +1 -5
  227. package/lib/utils/abstractdeployer.js.map +1 -1
  228. package/lib/utils/abstractdeployer.spec.js +6 -8
  229. package/lib/utils/abstractdeployer.spec.js.map +1 -1
  230. package/lib/utils/context.d.ts +61 -29
  231. package/lib/utils/context.js +133 -127
  232. package/lib/utils/context.js.map +1 -1
  233. package/lib/utils/context.spec.js +147 -153
  234. package/lib/utils/context.spec.js.map +1 -1
  235. package/lib/utils/cookie.d.ts +66 -45
  236. package/lib/utils/cookie.js +69 -158
  237. package/lib/utils/cookie.js.map +1 -1
  238. package/lib/utils/cookie.spec.js +220 -238
  239. package/lib/utils/cookie.spec.js.map +1 -1
  240. package/lib/utils/esm.d.ts +4 -0
  241. package/lib/utils/esm.js +10 -0
  242. package/lib/utils/esm.js.map +1 -0
  243. package/lib/utils/httpcontext.d.ts +37 -9
  244. package/lib/utils/httpcontext.js +86 -57
  245. package/lib/utils/httpcontext.js.map +1 -1
  246. package/lib/utils/httpcontext.spec.js +37 -48
  247. package/lib/utils/httpcontext.spec.js.map +1 -1
  248. package/lib/utils/logger.d.ts +2 -2
  249. package/lib/utils/logger.js +15 -28
  250. package/lib/utils/logger.js.map +1 -1
  251. package/lib/utils/logger.spec.js +9 -11
  252. package/lib/utils/logger.spec.js.map +1 -1
  253. package/lib/utils/serializers.js +17 -20
  254. package/lib/utils/serializers.js.map +1 -1
  255. package/lib/utils/serializers.spec.js +43 -44
  256. package/lib/utils/serializers.spec.js.map +1 -1
  257. package/lib/utils/session.d.ts +120 -0
  258. package/lib/utils/session.js +155 -0
  259. package/lib/utils/session.js.map +1 -0
  260. package/lib/utils/session.spec.d.ts +1 -0
  261. package/lib/utils/session.spec.js +66 -0
  262. package/lib/utils/session.spec.js.map +1 -0
  263. package/lib/utils/waiter.d.ts +1 -1
  264. package/lib/utils/waiter.js +32 -52
  265. package/lib/utils/waiter.js.map +1 -1
  266. package/lib/utils/waiter.spec.js +75 -92
  267. package/lib/utils/waiter.spec.js.map +1 -1
  268. package/package.json +22 -14
  269. package/test/config-invitation.json +1 -3
  270. package/test/config.json +3 -3
  271. package/test/config.old.json +1 -2
  272. package/test/moddas/annotatedservice.js +5 -5
  273. package/test/moddas/debugmailer.js +2 -3
  274. package/test/moddas/fakeservice.js +2 -3
  275. package/test/moddas/voidstore.js +6 -4
  276. package/test/models/ident.js +2 -6
  277. package/test/models/task.js +3 -7
  278. package/test/package.json +2 -1
  279. package/webda.module.json +956 -188
@@ -1,43 +1,28 @@
1
- "use strict";
2
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
6
  };
8
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
- return new (P || (P = Promise))(function (resolve, reject) {
11
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
- step((generator = generator.apply(thisArg, _arguments || [])).next());
15
- });
16
- };
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.Authentication = exports.AuthenticationParameters = void 0;
19
- const bcrypt = require("bcryptjs");
20
- const crypto = require("crypto");
21
- const service_1 = require("../services/service");
22
- const httpcontext_1 = require("../utils/httpcontext");
23
- class AuthenticationParameters extends service_1.ServiceParameters {
7
+ import bcrypt from "bcryptjs";
8
+ import { Inject, Route, Service, ServiceParameters } from "../services/service.js";
9
+ import { HttpContext } from "../utils/httpcontext.js";
10
+ export class AuthenticationParameters extends ServiceParameters {
24
11
  constructor(params) {
25
- var _a, _b, _c, _d, _e, _f;
26
- var _g, _h;
12
+ var _a, _b;
27
13
  super(params);
28
- (_a = this.identStore) !== null && _a !== void 0 ? _a : (this.identStore = "idents");
29
- (_b = this.userStore) !== null && _b !== void 0 ? _b : (this.userStore = "users");
30
- (_c = this.url) !== null && _c !== void 0 ? _c : (this.url = "/auth");
31
- (_d = this.password) !== null && _d !== void 0 ? _d : (this.password = {
14
+ this.identStore ?? (this.identStore = "idents");
15
+ this.userStore ?? (this.userStore = "users");
16
+ this.url ?? (this.url = "/auth");
17
+ this.password ?? (this.password = {
32
18
  regexp: ".{8,}"
33
19
  });
34
20
  if (this.email) {
35
- (_e = (_g = this.email).delay) !== null && _e !== void 0 ? _e : (_g.delay = 3600000 * 4);
36
- (_f = (_h = this.email).failedLoginBeforeDelay) !== null && _f !== void 0 ? _f : (_h.failedLoginBeforeDelay = 3);
21
+ (_a = this.email).delay ?? (_a.delay = 3600000 * 4);
22
+ (_b = this.email).failedLoginBeforeDelay ?? (_b.failedLoginBeforeDelay = 3);
37
23
  }
38
24
  }
39
25
  }
40
- exports.AuthenticationParameters = AuthenticationParameters;
41
26
  /**
42
27
  * This class is known as the Authentication module
43
28
  * It handles OAuth for several providers for now (Facebook, Google, Amazon, GitHub and Twitter)
@@ -61,7 +46,7 @@ exports.AuthenticationParameters = AuthenticationParameters;
61
46
  * @category CoreServices
62
47
  * @WebdaModda
63
48
  */
64
- class Authentication extends service_1.Service {
49
+ class Authentication extends Service {
65
50
  constructor() {
66
51
  super(...arguments);
67
52
  this.providers = new Set();
@@ -86,132 +71,6 @@ class Authentication extends service_1.Service {
86
71
  getIdentStore() {
87
72
  return this._identsStore;
88
73
  }
89
- /**
90
- * @override
91
- */
92
- initRoutes() {
93
- // ROUTES
94
- let url = this.parameters.url;
95
- // List authentication configured
96
- this.addRoute(url, ["GET", "DELETE"], this._listAuthentications, {
97
- get: {
98
- description: "Retrieve the list of available authentication",
99
- summary: "Get available auths",
100
- operationId: `getAuthenticationMethods`,
101
- responses: {
102
- "200": {
103
- description: "List of authentication"
104
- }
105
- }
106
- },
107
- delete: {
108
- description: "Logout current user",
109
- summary: "Logout",
110
- operationId: `logout`,
111
- responses: {
112
- "200": {}
113
- }
114
- }
115
- });
116
- // Get the current user
117
- this.addRoute(url + "/me", ["GET"], this._getMe, {
118
- get: {
119
- description: "Retrieve the current user from the session",
120
- summary: "Get current user",
121
- operationId: "getCurrentUser"
122
- }
123
- });
124
- if (this.parameters.email) {
125
- this.addProvider("email");
126
- // Add static for email for now, if set before it should have priority
127
- this.addRoute(url + "/email", ["POST"], this._handleEmail, {
128
- post: {
129
- description: "Authenticate with an email and password",
130
- summary: "Authenticate with email",
131
- operationId: `authWithEmail`
132
- }
133
- });
134
- this.addRoute(url + "/email/callback{?email,token,user}", ["GET"], this._handleEmailCallback, {
135
- hidden: true
136
- });
137
- this.addRoute(url + "/email/passwordRecovery", ["POST"], this._passwordRecovery, {
138
- post: {
139
- schemas: {
140
- input: {
141
- type: "object",
142
- properties: {
143
- token: {
144
- type: "string"
145
- },
146
- expire: {
147
- type: "number"
148
- },
149
- password: {
150
- type: "string"
151
- },
152
- login: {
153
- type: "string"
154
- }
155
- }
156
- }
157
- },
158
- description: "Reinit the password if we have the right token, expire",
159
- summary: "Reinit password",
160
- operationId: "reinitPassword",
161
- responses: {
162
- "204": {
163
- description: ""
164
- },
165
- "403": {
166
- description: "Wrong Token"
167
- }
168
- }
169
- }
170
- });
171
- this.addRoute(url + "/email/{email}/recover", ["GET"], this._passwordRecoveryEmail, {
172
- get: {
173
- description: "The password reset process will be start",
174
- summary: "Start password recovery",
175
- operationId: "startEmailRecovery",
176
- responses: {
177
- "204": {
178
- description: ""
179
- },
180
- "404": {
181
- description: "Email does not exist"
182
- },
183
- "429": {
184
- description: "Recovery has been initiated in the last 4 hours"
185
- }
186
- }
187
- }
188
- });
189
- this.addRoute(url + "/email/{email}/validate", ["GET"], this._sendEmailValidation, {
190
- get: {
191
- description: "The email validation process will be start",
192
- summary: "Restart email validation",
193
- operationId: "startEmailRecovery",
194
- responses: {
195
- "204": {
196
- description: ""
197
- },
198
- "409": {
199
- description: "Email already verified for another user"
200
- },
201
- "412": {
202
- description: "Email already verified for current user"
203
- },
204
- "429": {
205
- description: "Validation has been initiated in the last 4 hours"
206
- }
207
- }
208
- }
209
- });
210
- }
211
- }
212
- getUrl() {
213
- return this.parameters.url;
214
- }
215
74
  setIdents(identStore) {
216
75
  this._identsStore = identStore;
217
76
  }
@@ -230,6 +89,10 @@ class Authentication extends service_1.Service {
230
89
  if (this.parameters.email && this.getMailMan() === undefined) {
231
90
  throw Error("email authentication requires a Mailer service");
232
91
  }
92
+ // Add email provider
93
+ if (this.parameters.email) {
94
+ this.addProvider("email");
95
+ }
233
96
  }
234
97
  /**
235
98
  * Add a provider to the oauth scheme
@@ -238,6 +101,16 @@ class Authentication extends service_1.Service {
238
101
  addProvider(name) {
239
102
  this.providers.add(name);
240
103
  }
104
+ /**
105
+ * Ensure email is enabled for all emails routes
106
+ * @override
107
+ */
108
+ getUrl(url, methods) {
109
+ if (url.startsWith("./emails") && !this.parameters.email) {
110
+ return undefined;
111
+ }
112
+ return super.getUrl(url, methods);
113
+ }
241
114
  /**
242
115
  * Send or resend an email to validate the email address
243
116
  *
@@ -246,54 +119,50 @@ class Authentication extends service_1.Service {
246
119
  * @throws 412 if the email is already validated
247
120
  * @throws 429 if a validation email has been sent recently
248
121
  */
249
- _sendEmailValidation(ctx) {
250
- return __awaiter(this, void 0, void 0, function* () {
251
- let identKey = ctx.parameters.email + "_email";
252
- let ident = yield this._identsStore.get(identKey);
253
- if (!ident) {
254
- yield this._identsStore.save({
255
- uuid: `${ctx.parameters.email}_email`,
256
- _lastValidationEmail: Date.now(),
257
- _type: "email"
258
- });
122
+ async _sendEmailValidation(ctx) {
123
+ let identKey = ctx.parameters.email + "_email";
124
+ let ident = await this._identsStore.get(identKey);
125
+ if (!ident) {
126
+ await this._identsStore.save({
127
+ uuid: `${ctx.parameters.email}_email`,
128
+ _lastValidationEmail: Date.now(),
129
+ _type: "email"
130
+ });
131
+ }
132
+ else {
133
+ // If the ident is linked to someone else - might want to remove it
134
+ if (ident.getUser() !== ctx.getCurrentUserId()) {
135
+ throw 409;
259
136
  }
260
- else {
261
- // If the ident is linked to someone else - might want to remove it
262
- if (ident.getUser() !== ctx.getCurrentUserId()) {
263
- throw 409;
264
- }
265
- // If the email is already validated
266
- if (ident._validation) {
267
- throw 412;
268
- }
269
- //
270
- if (ident._lastValidationEmail >= Date.now() - this.parameters.email.delay) {
271
- throw 429;
272
- }
273
- yield this._identsStore.patch({
274
- _lastValidationEmail: Date.now(),
275
- uuid: identKey
276
- });
137
+ // If the email is already validated
138
+ if (ident._validation) {
139
+ throw 412;
277
140
  }
278
- yield this.sendValidationEmail(ctx, ctx.parameters.email);
279
- });
141
+ //
142
+ if (ident._lastValidationEmail >= Date.now() - this.parameters.email.delay) {
143
+ throw 429;
144
+ }
145
+ await this._identsStore.patch({
146
+ _lastValidationEmail: Date.now(),
147
+ uuid: identKey
148
+ });
149
+ }
150
+ await this.sendValidationEmail(ctx, ctx.parameters.email);
280
151
  }
281
152
  /**
282
153
  * Return current user
283
154
  * @param ctx
284
155
  */
285
- _getMe(ctx) {
286
- return __awaiter(this, void 0, void 0, function* () {
287
- let user = yield ctx.getCurrentUser();
288
- if (user === undefined) {
289
- throw 404;
290
- }
291
- yield this.emitSync("Authentication.GetMe", {
292
- context: ctx,
293
- user
294
- });
295
- ctx.write(user);
156
+ async _getMe(ctx) {
157
+ let user = await ctx.getCurrentUser();
158
+ if (user === undefined) {
159
+ throw 404;
160
+ }
161
+ await this.emitSync("Authentication.GetMe", {
162
+ context: ctx,
163
+ user
296
164
  });
165
+ ctx.write(user);
297
166
  }
298
167
  /**
299
168
  * Handle both list of available authentication
@@ -302,233 +171,223 @@ class Authentication extends service_1.Service {
302
171
  * @param ctx
303
172
  * @returns
304
173
  */
305
- _listAuthentications(ctx) {
306
- return __awaiter(this, void 0, void 0, function* () {
307
- if (ctx.getHttpContext().getMethod() === "DELETE") {
308
- yield this.logout(ctx);
309
- ctx.write("GoodBye");
310
- return;
311
- }
312
- ctx.write(Array.from(this.providers));
313
- });
174
+ async _listAuthentications(ctx) {
175
+ if (ctx.getHttpContext().getMethod() === "DELETE") {
176
+ await this.logout(ctx);
177
+ ctx.write("GoodBye");
178
+ return;
179
+ }
180
+ ctx.write(Array.from(this.providers));
314
181
  }
315
- onIdentLogin(ctx, provider, identId, profile, tokens = undefined) {
316
- return __awaiter(this, void 0, void 0, function* () {
317
- // Auto postifx with provider name
318
- const postfix = `_${provider}`;
319
- if (!identId.endsWith(postfix)) {
320
- identId += postfix;
321
- }
322
- let ident = yield this._identsStore.get(identId);
323
- // Ident is known
182
+ async onIdentLogin(ctx, provider, identId, profile, tokens = undefined) {
183
+ // Auto postifx with provider name
184
+ const postfix = `_${provider}`;
185
+ if (!identId.endsWith(postfix)) {
186
+ identId += postfix;
187
+ }
188
+ let ident = await this._identsStore.get(identId);
189
+ // Ident is known
190
+ if (ident) {
191
+ await this.login(ctx, ident.getUser(), ident);
192
+ await this._identsStore.patch({
193
+ _lastUsed: new Date(),
194
+ __tokens: tokens,
195
+ uuid: ident.uuid
196
+ });
197
+ // Redirect to?
198
+ return;
199
+ }
200
+ let user;
201
+ if (profile.email) {
202
+ ident = await this._identsStore.get(`${profile.email}_email`);
203
+ }
204
+ // If already login
205
+ if (ctx.getCurrentUserId()) {
206
+ user = await ctx.getCurrentUser();
207
+ }
208
+ else {
209
+ // If an email in profile try to find the ident
324
210
  if (ident) {
325
- yield this.login(ctx, ident.getUser(), ident);
326
- yield this._identsStore.patch({
327
- _lastUsed: new Date(),
328
- __tokens: tokens,
329
- uuid: ident.uuid
330
- });
331
- // Redirect to?
332
- return;
333
- }
334
- let user;
335
- if (profile.email) {
336
- ident = yield this._identsStore.get(`${profile.email}_email`);
211
+ user = await this._usersStore.get(ident.getUser());
337
212
  }
338
- // If already login
339
- if (ctx.getCurrentUserId()) {
340
- user = yield ctx.getCurrentUser();
341
- }
342
- else {
343
- // If an email in profile try to find the ident
344
- if (ident) {
345
- user = yield this._usersStore.get(ident.getUser());
346
- }
347
- if (!user) {
348
- // If no user, register a new user automatically
349
- user = yield this.registerUser(ctx, profile, identId);
350
- yield this._usersStore.save(user);
351
- }
352
- }
353
- if (profile.email && !ident) {
354
- // Save additional email
355
- ident = this._identsStore.initModel({
356
- uuid: `${profile.email}_email`,
357
- provider: "email"
358
- });
359
- ident.setUser(user.getUuid());
360
- yield ident.save();
213
+ if (!user) {
214
+ // If no user, register a new user automatically
215
+ user = await this.registerUser(ctx, profile, identId);
216
+ await this._usersStore.save(user);
361
217
  }
362
- // Work directly on ident argument
218
+ }
219
+ if (profile.email && !ident) {
220
+ // Save additional email
363
221
  ident = this._identsStore.initModel({
364
- uuid: identId,
365
- profile,
366
- __tokens: tokens,
367
- provider
222
+ uuid: `${profile.email}_email`,
223
+ provider: "email"
368
224
  });
369
- ident.setUser(user.uuid);
370
- ident._lastUsed = new Date();
371
- ident.setType(provider);
372
- yield ident.save();
373
- ident.__new = true;
374
- yield this.login(ctx, user, ident);
225
+ ident.setUser(user.getUuid());
226
+ await ident.save();
227
+ }
228
+ // Work directly on ident argument
229
+ ident = this._identsStore.initModel({
230
+ uuid: identId,
231
+ profile,
232
+ __tokens: tokens,
233
+ provider
375
234
  });
235
+ ident.setUser(user.uuid);
236
+ ident._lastUsed = new Date();
237
+ ident.setType(provider);
238
+ await ident.save();
239
+ ident.__new = true;
240
+ await this.login(ctx, user, ident);
376
241
  }
377
242
  /**
378
243
  * Create a new User with the link ident
379
244
  * @param ident
380
245
  */
381
- createUserWithIdent(provider, identId, profile = {}) {
382
- return __awaiter(this, void 0, void 0, function* () {
383
- if (yield this._identsStore.exists(`${identId}_${provider}`)) {
384
- throw new Error("Ident is already known");
385
- }
386
- let ctx = yield this._webda.newContext(new httpcontext_1.HttpContext("fake", "GET", "/"));
387
- // Pretend we logged in with the ident
388
- yield this.onIdentLogin(ctx, provider, identId, profile);
389
- });
390
- }
391
- registerUser(ctx, data, identId, user = this._usersStore.initModel()) {
392
- return __awaiter(this, void 0, void 0, function* () {
393
- user.email = data.email;
394
- user.locale = ctx.getLocale();
395
- yield this.emitSync("Authentication.Register", {
396
- user: user,
397
- data: data,
398
- context: ctx,
399
- identId
400
- });
401
- return user;
246
+ async createUserWithIdent(provider, identId, profile = {}) {
247
+ if (await this._identsStore.exists(`${identId}_${provider}`)) {
248
+ throw new Error("Ident is already known");
249
+ }
250
+ let ctx = await this._webda.newContext(new HttpContext("fake", "GET", "/"));
251
+ // Pretend we logged in with the ident
252
+ await this.onIdentLogin(ctx, provider, identId, profile);
253
+ }
254
+ async registerUser(ctx, data, identId, user = this._usersStore.initModel()) {
255
+ user.email = data.email;
256
+ user.locale = ctx.getLocale();
257
+ await this.emitSync("Authentication.Register", {
258
+ user: user,
259
+ data: data,
260
+ context: ctx,
261
+ identId
402
262
  });
263
+ return user;
403
264
  }
404
- getPasswordRecoveryInfos(uuid, interval = this.parameters.email.delay) {
405
- return __awaiter(this, void 0, void 0, function* () {
406
- var expire = Date.now() + interval;
407
- let user;
408
- if (typeof uuid === "string") {
409
- user = yield this._usersStore.get(uuid);
410
- }
411
- else {
412
- user = uuid;
413
- }
414
- if (!user) {
415
- return undefined;
416
- }
417
- return {
418
- expire: expire,
419
- // Might want to add more alea not coming from the db to avoid exploitation of stolen db
420
- token: this.hashInfo(user.uuid + expire + user.getPassword()),
421
- login: user.uuid
422
- };
423
- });
265
+ async getPasswordRecoveryInfos(uuid, interval = this.parameters.email.delay) {
266
+ const expire = Date.now() + interval;
267
+ let user;
268
+ if (typeof uuid === "string") {
269
+ user = await this._usersStore.get(uuid);
270
+ }
271
+ else {
272
+ user = uuid;
273
+ }
274
+ if (!user) {
275
+ return undefined;
276
+ }
277
+ return {
278
+ expire: expire,
279
+ // Might want to add more alea not coming from the db to avoid exploitation of stolen db
280
+ token: await this.cryptoService.hmac(user.uuid + expire + user.getPassword()),
281
+ login: user.uuid
282
+ };
424
283
  }
425
- _passwordRecoveryEmail(ctx) {
426
- return __awaiter(this, void 0, void 0, function* () {
427
- let email = ctx.parameter("email");
428
- let ident = yield this._identsStore.get(email + "_email");
429
- if (!ident) {
430
- throw 404;
431
- }
432
- let user = yield this._usersStore.get(ident.getUser());
433
- // Dont allow to do too many request
434
- if (!user.lastPasswordRecoveryBefore(Date.now() - this.parameters.email.delay)) {
435
- throw 429;
436
- }
437
- yield this._usersStore.patch({
438
- _lastPasswordRecovery: Date.now(),
439
- uuid: user.uuid
440
- });
441
- yield this.sendRecoveryEmail(ctx, user, email);
284
+ /**
285
+ * Manage password recovery
286
+ * @param ctx
287
+ */
288
+ async _passwordRecoveryEmail(ctx) {
289
+ let email = ctx.parameter("email");
290
+ let ident = await this._identsStore.get(email + "_email");
291
+ if (!ident) {
292
+ throw 404;
293
+ }
294
+ let user = await this._usersStore.get(ident.getUser());
295
+ // Dont allow to do too many request
296
+ if (!user.lastPasswordRecoveryBefore(Date.now() - this.parameters.email.delay)) {
297
+ throw 429;
298
+ }
299
+ await this._usersStore.patch({
300
+ _lastPasswordRecovery: Date.now(),
301
+ uuid: user.uuid
442
302
  });
303
+ await this.sendRecoveryEmail(ctx, user, email);
443
304
  }
444
- _verifyPassword(password, user) {
445
- return __awaiter(this, void 0, void 0, function* () {
446
- if (this._passwordVerifier) {
447
- if (!(yield this._passwordVerifier.validate(password, user))) {
448
- throw 400;
449
- }
450
- return;
451
- }
452
- let regexp = new RegExp(this.parameters.password.regexp);
453
- if (regexp.exec(password) === null) {
305
+ async _verifyPassword(password, user) {
306
+ if (this._passwordVerifier) {
307
+ if (!(await this._passwordVerifier.validate(password, user))) {
454
308
  throw 400;
455
309
  }
310
+ return;
311
+ }
312
+ let regexp = new RegExp(this.parameters.password.regexp);
313
+ if (regexp.exec(password) === null) {
314
+ throw 400;
315
+ }
316
+ }
317
+ async _passwordRecovery(ctx) {
318
+ let body = await ctx.getRequestBody();
319
+ if (body.password === undefined ||
320
+ body.login === undefined ||
321
+ body.token === undefined ||
322
+ body.expire === undefined) {
323
+ throw 400;
324
+ }
325
+ let user = await this._usersStore.get(body.login.toLowerCase());
326
+ if (!user) {
327
+ throw 403;
328
+ }
329
+ if (!(await this.cryptoService.hmacVerify(body.login.toLowerCase() + body.expire + user.getPassword(), body.token))) {
330
+ throw 403;
331
+ }
332
+ if (body.expire < Date.now()) {
333
+ throw 410;
334
+ }
335
+ await this._verifyPassword(body.password, user);
336
+ let password = this.hashPassword(body.password);
337
+ await this._usersStore.patch({
338
+ __password: password,
339
+ uuid: body.login.toLowerCase()
340
+ });
341
+ await this.emitSync("Authentication.PasswordUpdate", {
342
+ user,
343
+ password,
344
+ context: ctx
456
345
  });
457
346
  }
458
- _passwordRecovery(ctx) {
459
- return __awaiter(this, void 0, void 0, function* () {
460
- let body = yield ctx.getRequestBody();
461
- if (body.password === undefined ||
462
- body.login === undefined ||
463
- body.token === undefined ||
464
- body.expire === undefined) {
465
- throw 400;
466
- }
467
- let user = yield this._usersStore.get(body.login.toLowerCase());
468
- if (!user) {
469
- throw 403;
470
- }
471
- if (body.token !== this.hashInfo(body.login.toLowerCase() + body.expire + user.getPassword())) {
472
- throw 403;
473
- }
474
- if (body.expire < Date.now()) {
475
- throw 410;
476
- }
477
- yield this._verifyPassword(body.password, user);
478
- let password = this.hashPassword(body.password);
479
- yield this._usersStore.patch({
480
- __password: password,
481
- uuid: body.login.toLowerCase()
347
+ /**
348
+ * Callback to validate an email address
349
+ * @param ctx
350
+ * @returns
351
+ */
352
+ async _handleEmailCallback(ctx) {
353
+ if (!ctx.parameter("token")) {
354
+ throw 400;
355
+ }
356
+ if (!(await this.cryptoService.hmacVerify(`${ctx.parameter("email")}_${ctx.parameter("user")}`, ctx.parameter("token")))) {
357
+ ctx.writeHead(302, {
358
+ Location: this.parameters.failureRedirect + "?reason=badToken"
482
359
  });
483
- yield this.emitSync("Authentication.PasswordUpdate", {
484
- user,
485
- password,
486
- context: ctx
360
+ return;
361
+ }
362
+ if (ctx.parameter("user") !== ctx.getCurrentUserId() &&
363
+ ctx.getCurrentUserId() !== "" &&
364
+ ctx.getCurrentUserId() !== undefined) {
365
+ ctx.writeHead(302, {
366
+ Location: this.parameters.failureRedirect + "?reason=badUser"
487
367
  });
488
- });
489
- }
490
- _handleEmailCallback(ctx) {
491
- return __awaiter(this, void 0, void 0, function* () {
492
- if (!ctx.parameter("token")) {
493
- throw 400;
494
- }
495
- let validation = ctx.parameter("token");
496
- if (validation !== this.generateEmailValidationToken(ctx.parameter("user"), ctx.parameter("email"))) {
497
- ctx.writeHead(302, {
498
- Location: this.parameters.failureRedirect + "?reason=badToken"
499
- });
500
- return;
501
- }
502
- if (ctx.parameter("user") !== ctx.getCurrentUserId() &&
503
- ctx.getCurrentUserId() !== "" &&
504
- ctx.getCurrentUserId() !== undefined) {
505
- ctx.writeHead(302, {
506
- Location: this.parameters.failureRedirect + "?reason=badUser"
507
- });
508
- return;
509
- }
510
- if (!ctx.parameter("user")) {
511
- ctx.writeHead(302, {
512
- Location: `${this.parameters.registerRedirect}?token=${ctx.parameter("token")}&email=${ctx.parameter("email")}`
513
- });
514
- return;
515
- }
516
- var uuid = ctx.parameter("email") + "_email";
517
- let ident = yield this._identsStore.get(uuid);
518
- // Would mean the ident got delete in the mean time... hyper low likely hood
519
- if (ident === undefined) {
520
- ident = this._identsStore.initModel({
521
- uuid
522
- });
523
- }
524
- ident._type = "email";
525
- ident._validation = new Date();
526
- ident.setUser(ctx.parameter("user"));
527
- yield ident.save();
368
+ return;
369
+ }
370
+ if (!ctx.parameter("user")) {
528
371
  ctx.writeHead(302, {
529
- Location: this.parameters.successRedirect + "?validation=email",
530
- "X-Webda-Authentication": "success"
372
+ Location: `${this.parameters.registerRedirect}?token=${ctx.parameter("token")}&email=${ctx.parameter("email")}`
373
+ });
374
+ return;
375
+ }
376
+ const uuid = ctx.parameter("email") + "_email";
377
+ let ident = await this._identsStore.get(uuid);
378
+ // Would mean the ident got delete in the mean time... hyper low likely hood
379
+ if (ident === undefined) {
380
+ ident = this._identsStore.initModel({
381
+ uuid
531
382
  });
383
+ }
384
+ ident._type = "email";
385
+ ident._validation = new Date();
386
+ ident.setUser(ctx.parameter("user"));
387
+ await ident.save();
388
+ ctx.writeHead(302, {
389
+ Location: this.parameters.successRedirect + "?validation=email",
390
+ "X-Webda-Authentication": "success"
532
391
  });
533
392
  }
534
393
  /**
@@ -539,19 +398,17 @@ class Authentication extends service_1.Service {
539
398
  * @param email
540
399
  * @returns
541
400
  */
542
- sendRecoveryEmail(ctx, user, email) {
543
- return __awaiter(this, void 0, void 0, function* () {
544
- let infos = yield this.getPasswordRecoveryInfos(user);
545
- var mailer = this.getMailMan();
546
- let locale = user.locale || ctx.getLocale();
547
- let mailOptions = {
548
- to: email,
549
- locale: locale,
550
- template: "EMAIL_RECOVERY",
551
- replacements: Object.assign(Object.assign({}, this.parameters.email), { infos, to: email, context: ctx })
552
- };
553
- return mailer.send(mailOptions);
554
- });
401
+ async sendRecoveryEmail(ctx, user, email) {
402
+ let infos = await this.getPasswordRecoveryInfos(user);
403
+ const mailer = this.getMailMan();
404
+ let locale = user.locale || ctx.getLocale();
405
+ let mailOptions = {
406
+ to: email,
407
+ locale: locale,
408
+ template: "EMAIL_RECOVERY",
409
+ replacements: { ...this.parameters.email, infos, to: email, context: ctx }
410
+ };
411
+ return mailer.send(mailOptions);
555
412
  }
556
413
  /**
557
414
  * Send an email to validate the user email by sending a unique link to
@@ -561,33 +418,26 @@ class Authentication extends service_1.Service {
561
418
  * @param email
562
419
  * @returns
563
420
  */
564
- sendValidationEmail(ctx, email) {
565
- return __awaiter(this, void 0, void 0, function* () {
566
- var mailer = this.getMailMan();
567
- let replacements = Object.assign(Object.assign({}, this.parameters.email), { context: ctx, url: ctx
568
- .getHttpContext()
569
- .getAbsoluteUrl(`${this.parameters.url}/email/callback?email=${email}&token=${this.generateEmailValidationToken(ctx.getCurrentUserId(), email)}`) });
570
- let userId = ctx.getCurrentUserId();
571
- if (userId && userId.length > 0) {
572
- replacements.url += "&user=" + userId;
573
- }
574
- let mailOptions = {
575
- to: email,
576
- locale: ctx.getLocale(),
577
- template: "EMAIL_REGISTER",
578
- replacements: replacements
579
- };
580
- return mailer.send(mailOptions);
581
- });
582
- }
583
- /**
584
- * Create a SHA256 of the info
585
- *
586
- * @param info to hash
587
- */
588
- hashInfo(info) {
589
- var hash = crypto.createHash("sha256");
590
- return hash.update(info).digest("hex");
421
+ async sendValidationEmail(ctx, email) {
422
+ const mailer = this.getMailMan();
423
+ let replacements = {
424
+ ...this.parameters.email,
425
+ context: ctx,
426
+ url: ctx
427
+ .getHttpContext()
428
+ .getAbsoluteUrl(`${this.parameters.url}/email/callback?email=${email}&token=${await this.generateEmailValidationToken(ctx.getCurrentUserId(), email)}`)
429
+ };
430
+ let userId = ctx.getCurrentUserId();
431
+ if (userId && userId.length > 0) {
432
+ replacements.url += "&user=" + userId;
433
+ }
434
+ let mailOptions = {
435
+ to: email,
436
+ locale: ctx.getLocale(),
437
+ template: "EMAIL_REGISTER",
438
+ replacements: replacements
439
+ };
440
+ return mailer.send(mailOptions);
591
441
  }
592
442
  /**
593
443
  * Check the password match the stored hash
@@ -608,13 +458,11 @@ class Authentication extends service_1.Service {
608
458
  /**
609
459
  * Logout user
610
460
  */
611
- logout(ctx) {
612
- return __awaiter(this, void 0, void 0, function* () {
613
- yield this.emitSync("Authentication.Logout", {
614
- context: ctx
615
- });
616
- ctx.getSession().destroy();
461
+ async logout(ctx) {
462
+ await this.emitSync("Authentication.Logout", {
463
+ context: ctx
617
464
  });
465
+ ctx.newSession();
618
466
  }
619
467
  /**
620
468
  * Login a user
@@ -624,25 +472,23 @@ class Authentication extends service_1.Service {
624
472
  * @param ident
625
473
  * @returns
626
474
  */
627
- login(ctx, user, ident) {
628
- return __awaiter(this, void 0, void 0, function* () {
629
- var event = {
630
- context: ctx,
631
- userId: "",
632
- identId: ident.uuid,
633
- ident
634
- };
635
- if (typeof user == "object") {
636
- event.userId = user.uuid;
637
- event.user = user;
638
- }
639
- else {
640
- event.userId = user;
641
- }
642
- event.context = ctx;
643
- ctx.getSession().login(event.userId, event.identId);
644
- return this.emitSync("Authentication.Login", event);
645
- });
475
+ async login(ctx, user, ident) {
476
+ const event = {
477
+ context: ctx,
478
+ userId: "",
479
+ identId: ident.uuid,
480
+ ident
481
+ };
482
+ if (typeof user == "object") {
483
+ event.userId = user.uuid;
484
+ event.user = user;
485
+ }
486
+ else {
487
+ event.userId = user;
488
+ }
489
+ event.context = ctx;
490
+ ctx.getSession().login(event.userId, event.identId);
491
+ return this.emitSync("Authentication.Login", event);
646
492
  }
647
493
  getMailMan() {
648
494
  return this.getService(this.parameters.email.mailer ? this.parameters.email.mailer : "Mailer");
@@ -653,40 +499,37 @@ class Authentication extends service_1.Service {
653
499
  * @param ctx
654
500
  * @param ident
655
501
  */
656
- handleLogin(ctx, ident) {
657
- var _a;
658
- return __awaiter(this, void 0, void 0, function* () {
659
- let updates = {};
660
- let user = yield this._usersStore.get(ident.getUser());
661
- // Check password
662
- if (this.checkPassword(user.getPassword(), (yield ctx.getRequestBody()).password)) {
663
- if (ident._failedLogin > 0) {
664
- ident._failedLogin = 0;
665
- }
666
- updates._lastUsed = new Date();
667
- updates._failedLogin = 0;
668
- updates.uuid = ident.uuid;
669
- yield this._identsStore.patch(updates);
670
- yield this.login(ctx, ident.getUser(), ident);
671
- ctx.write(user);
672
- }
673
- else {
674
- yield this.emitSync("Authentication.LoginFailed", {
675
- user,
676
- context: ctx
677
- });
678
- (_a = ident._failedLogin) !== null && _a !== void 0 ? _a : (ident._failedLogin = 0);
679
- updates._failedLogin = ident._failedLogin + 1;
680
- updates._lastFailedLogin = new Date();
681
- updates.uuid = ident.uuid;
682
- // Swalow exeception issue to double check !
683
- yield this._identsStore.patch(updates);
684
- // Allows to auto redirect user to a oauth if needed
685
- if (!ctx.isEnded()) {
686
- throw 403;
687
- }
502
+ async handleLogin(ctx, ident) {
503
+ let updates = {};
504
+ let user = await this._usersStore.get(ident.getUser());
505
+ // Check password
506
+ if (this.checkPassword(user.getPassword(), (await ctx.getRequestBody()).password)) {
507
+ if (ident._failedLogin > 0) {
508
+ ident._failedLogin = 0;
509
+ }
510
+ updates._lastUsed = new Date();
511
+ updates._failedLogin = 0;
512
+ updates.uuid = ident.uuid;
513
+ await this._identsStore.patch(updates);
514
+ await this.login(ctx, ident.getUser(), ident);
515
+ ctx.write(user);
516
+ }
517
+ else {
518
+ await this.emitSync("Authentication.LoginFailed", {
519
+ user,
520
+ context: ctx
521
+ });
522
+ ident._failedLogin ?? (ident._failedLogin = 0);
523
+ updates._failedLogin = ident._failedLogin + 1;
524
+ updates._lastFailedLogin = new Date();
525
+ updates.uuid = ident.uuid;
526
+ // Swalow exeception issue to double check !
527
+ await this._identsStore.patch(updates);
528
+ // Allows to auto redirect user to a oauth if needed
529
+ if (!ctx.isEnded()) {
530
+ throw 403;
688
531
  }
689
- });
532
+ }
690
533
  }
691
534
  /**
692
535
  * Handle the POST /auth/email
@@ -694,95 +537,220 @@ class Authentication extends service_1.Service {
694
537
  * @param ctx
695
538
  * @returns
696
539
  */
697
- _handleEmail(ctx) {
698
- return __awaiter(this, void 0, void 0, function* () {
699
- // If called while logged in reject
700
- if (ctx.getCurrentUserId() !== undefined) {
701
- throw 410;
540
+ async _handleEmail(ctx) {
541
+ // If called while logged in reject
542
+ if (ctx.getCurrentUserId() !== undefined) {
543
+ throw 410;
544
+ }
545
+ let body = await ctx.getRequestBody();
546
+ if (body.login === undefined) {
547
+ throw 400;
548
+ }
549
+ const mailConfig = this.parameters.email;
550
+ const uuid = body.login.toLowerCase() + "_email";
551
+ let ident = await this._identsStore.get(uuid);
552
+ if (ident !== undefined && ident.getUser() !== undefined) {
553
+ // Register on an known user
554
+ if (!body.register) {
555
+ await this.handleLogin(ctx, ident);
556
+ return;
702
557
  }
703
- let body = yield ctx.getRequestBody();
704
- if (body.login === undefined) {
705
- throw 400;
558
+ // If register on a validate email
559
+ if (ident._validation !== undefined) {
560
+ throw 409;
706
561
  }
707
- var mailConfig = this.parameters.email;
708
- var uuid = body.login.toLowerCase() + "_email";
709
- let ident = yield this._identsStore.get(uuid);
710
- if (ident !== undefined && ident.getUser() !== undefined) {
711
- // Register on an known user
712
- if (!body.register) {
713
- yield this.handleLogin(ctx, ident);
714
- return;
562
+ }
563
+ // TODO Handle add of email on authenticated user
564
+ const email = body.login.toLowerCase();
565
+ // Read the form
566
+ if (body.register) {
567
+ let validation = undefined;
568
+ // Need to check email before creation
569
+ if (!mailConfig.postValidation) {
570
+ if (body.token && (await this.cryptoService.hmacVerify(`${email}_${ctx.getCurrentUserId()}`, body.token))) {
571
+ validation = new Date();
715
572
  }
716
- // If register on a validate email
717
- if (ident._validation !== undefined) {
718
- throw 409;
573
+ else {
574
+ ctx.write({});
575
+ // token is undefined send an email
576
+ return this.sendValidationEmail(ctx, email);
719
577
  }
720
578
  }
721
- // TODO Handle add of email on authenticated user
722
- var email = body.login.toLowerCase();
723
- // Read the form
724
- if (body.register) {
725
- var validation = undefined;
726
- // Need to check email before creation
727
- if (!mailConfig.postValidation) {
728
- if (body.token == this.generateEmailValidationToken(ctx.getCurrentUserId(), email)) {
729
- validation = new Date();
730
- }
731
- else {
732
- ctx.write({});
733
- // token is undefined send an email
734
- return this.sendValidationEmail(ctx, email);
735
- }
736
- }
737
- if (!body.password) {
738
- throw 400;
739
- }
740
- // Store with a _
741
- let __password = this.hashPassword(body.password);
742
- yield this._verifyPassword(body.password);
743
- // Remove useless attributes
744
- delete body.password;
745
- delete body.register;
746
- delete body.token;
747
- let user = yield this.registerUser(ctx, {}, uuid, Object.assign(Object.assign({}, body), { __password }));
748
- yield this.emitSync("Authentication.PasswordCreate", {
749
- user,
750
- password: __password,
751
- context: ctx
752
- });
753
- user = yield this._usersStore.save(user);
754
- var newIdent = this._identsStore.initModel({
755
- uuid: uuid,
756
- _type: "email",
757
- email: email
758
- });
759
- newIdent.setUser(user.uuid);
760
- if (validation) {
761
- newIdent._validation = validation;
762
- }
763
- else if (!mailConfig.skipEmailValidation) {
764
- newIdent._lastValidationEmail = Date.now();
765
- }
766
- ident = yield newIdent.save();
767
- yield this.login(ctx, user, ident);
768
- ctx.write(user);
769
- if (!validation && !mailConfig.skipEmailValidation) {
770
- yield this.sendValidationEmail(ctx, email);
771
- }
772
- return;
579
+ if (!body.password) {
580
+ throw 400;
773
581
  }
774
- throw 404;
775
- });
582
+ // Store with a _
583
+ let __password = this.hashPassword(body.password);
584
+ await this._verifyPassword(body.password);
585
+ // Remove useless attributes
586
+ delete body.password;
587
+ delete body.register;
588
+ delete body.token;
589
+ let user = await this.registerUser(ctx, {}, uuid, { ...body, __password });
590
+ await this.emitSync("Authentication.PasswordCreate", {
591
+ user,
592
+ password: __password,
593
+ context: ctx
594
+ });
595
+ user = await this._usersStore.save(user);
596
+ const newIdent = this._identsStore.initModel({
597
+ uuid: uuid,
598
+ _type: "email",
599
+ email: email
600
+ });
601
+ newIdent.setUser(user.uuid);
602
+ if (validation) {
603
+ newIdent._validation = validation;
604
+ }
605
+ else if (!mailConfig.skipEmailValidation) {
606
+ newIdent._lastValidationEmail = Date.now();
607
+ }
608
+ ident = await newIdent.save();
609
+ await this.login(ctx, user, ident);
610
+ ctx.write(user);
611
+ if (!validation && !mailConfig.skipEmailValidation) {
612
+ await this.sendValidationEmail(ctx, email);
613
+ }
614
+ return;
615
+ }
616
+ throw 404;
776
617
  }
777
- generateEmailValidationToken(user, email) {
778
- return this.hashInfo(email + "_" + this._webda.getSecret() + user);
618
+ async generateEmailValidationToken(user, email) {
619
+ return this.cryptoService.hmac(email + "_" + user);
779
620
  }
780
621
  }
781
622
  __decorate([
782
- (0, service_1.Inject)("identStore", "idents")
623
+ Inject("identStore", "idents")
783
624
  ], Authentication.prototype, "_identsStore", void 0);
784
625
  __decorate([
785
- (0, service_1.Inject)("userStore", "users")
626
+ Inject("userStore", "users")
786
627
  ], Authentication.prototype, "_usersStore", void 0);
787
- exports.Authentication = Authentication;
628
+ __decorate([
629
+ Inject("CryptoService")
630
+ ], Authentication.prototype, "cryptoService", void 0);
631
+ __decorate([
632
+ Route("./email/{email}/validate", ["GET"], false, {
633
+ get: {
634
+ description: "The email validation process will be start",
635
+ summary: "Restart email validation",
636
+ operationId: "startEmailRecovery",
637
+ responses: {
638
+ "204": {
639
+ description: ""
640
+ },
641
+ "409": {
642
+ description: "Email already verified for another user"
643
+ },
644
+ "412": {
645
+ description: "Email already verified for current user"
646
+ },
647
+ "429": {
648
+ description: "Validation has been initiated in the last 4 hours"
649
+ }
650
+ }
651
+ }
652
+ })
653
+ ], Authentication.prototype, "_sendEmailValidation", null);
654
+ __decorate([
655
+ Route("./me", ["GET"], false, {
656
+ get: {
657
+ description: "Retrieve the current user from the session",
658
+ summary: "Get current user",
659
+ operationId: "getCurrentUser"
660
+ }
661
+ })
662
+ ], Authentication.prototype, "_getMe", null);
663
+ __decorate([
664
+ Route(".", ["GET", "DELETE"], false, {
665
+ get: {
666
+ description: "Retrieve the list of available authentication",
667
+ summary: "Get available auths",
668
+ operationId: `getAuthenticationMethods`,
669
+ responses: {
670
+ "200": {
671
+ description: "List of authentication"
672
+ }
673
+ }
674
+ },
675
+ delete: {
676
+ description: "Logout current user",
677
+ summary: "Logout",
678
+ operationId: `logout`,
679
+ responses: {
680
+ "200": {}
681
+ }
682
+ }
683
+ })
684
+ ], Authentication.prototype, "_listAuthentications", null);
685
+ __decorate([
686
+ Route("./email/{email}/recover", ["GET"], false, {
687
+ get: {
688
+ description: "The password reset process will be start",
689
+ summary: "Start password recovery",
690
+ operationId: "startEmailRecovery",
691
+ responses: {
692
+ "204": {
693
+ description: ""
694
+ },
695
+ "404": {
696
+ description: "Email does not exist"
697
+ },
698
+ "429": {
699
+ description: "Recovery has been initiated in the last 4 hours"
700
+ }
701
+ }
702
+ }
703
+ })
704
+ ], Authentication.prototype, "_passwordRecoveryEmail", null);
705
+ __decorate([
706
+ Route("./email/passwordRecovery", ["POST"], false, {
707
+ post: {
708
+ schemas: {
709
+ input: {
710
+ type: "object",
711
+ properties: {
712
+ token: {
713
+ type: "string"
714
+ },
715
+ expire: {
716
+ type: "number"
717
+ },
718
+ password: {
719
+ type: "string"
720
+ },
721
+ login: {
722
+ type: "string"
723
+ }
724
+ }
725
+ }
726
+ },
727
+ description: "Reinit the password if we have the right token, expire",
728
+ summary: "Reinit password",
729
+ operationId: "reinitPassword",
730
+ responses: {
731
+ "204": {
732
+ description: ""
733
+ },
734
+ "403": {
735
+ description: "Wrong Token"
736
+ }
737
+ }
738
+ }
739
+ })
740
+ ], Authentication.prototype, "_passwordRecovery", null);
741
+ __decorate([
742
+ Route("./email/callback{?email,token,user}", ["GET"], false, {
743
+ hidden: true
744
+ })
745
+ ], Authentication.prototype, "_handleEmailCallback", null);
746
+ __decorate([
747
+ Route("./email", ["POST"], false, {
748
+ post: {
749
+ description: "Authenticate with an email and password",
750
+ summary: "Authenticate with email",
751
+ operationId: `authWithEmail`
752
+ }
753
+ })
754
+ ], Authentication.prototype, "_handleEmail", null);
755
+ export { Authentication };
788
756
  //# sourceMappingURL=authentication.js.map