@things-factory/auth-base 7.0.0-alpha.8 → 7.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 (311) hide show
  1. package/client/actions/auth.ts +3 -3
  2. package/dist-client/actions/auth.d.ts +3 -3
  3. package/dist-client/actions/auth.js.map +1 -1
  4. package/dist-client/auth.js.map +1 -1
  5. package/dist-client/directive/privileged.d.ts +4 -4
  6. package/dist-client/directive/privileged.js.map +1 -1
  7. package/dist-client/profiled.js.map +1 -1
  8. package/dist-client/reducers/auth.js.map +1 -1
  9. package/dist-client/tsconfig.tsbuildinfo +1 -1
  10. package/dist-server/constants/error-code.d.ts +3 -0
  11. package/dist-server/constants/error-code.js +4 -1
  12. package/dist-server/constants/error-code.js.map +1 -1
  13. package/dist-server/controllers/change-pwd.js +1 -2
  14. package/dist-server/controllers/change-pwd.js.map +1 -1
  15. package/dist-server/controllers/checkin.js +1 -2
  16. package/dist-server/controllers/checkin.js.map +1 -1
  17. package/dist-server/controllers/delete-user.js +2 -3
  18. package/dist-server/controllers/delete-user.js.map +1 -1
  19. package/dist-server/controllers/invitation.js +4 -5
  20. package/dist-server/controllers/invitation.js.map +1 -1
  21. package/dist-server/controllers/profile.d.ts +1 -0
  22. package/dist-server/controllers/profile.js +1 -2
  23. package/dist-server/controllers/profile.js.map +1 -1
  24. package/dist-server/controllers/reset-password.js +2 -3
  25. package/dist-server/controllers/reset-password.js.map +1 -1
  26. package/dist-server/controllers/signin.js +1 -2
  27. package/dist-server/controllers/signin.js.map +1 -1
  28. package/dist-server/controllers/signup.js +1 -2
  29. package/dist-server/controllers/signup.js.map +1 -1
  30. package/dist-server/controllers/unlock-user.js +2 -3
  31. package/dist-server/controllers/unlock-user.js.map +1 -1
  32. package/dist-server/controllers/utils/make-invitation-token.js +1 -2
  33. package/dist-server/controllers/utils/make-invitation-token.js.map +1 -1
  34. package/dist-server/controllers/utils/make-verification-token.js +1 -2
  35. package/dist-server/controllers/utils/make-verification-token.js.map +1 -1
  36. package/dist-server/controllers/utils/password-rule.js +10 -10
  37. package/dist-server/controllers/utils/password-rule.js.map +1 -1
  38. package/dist-server/controllers/utils/save-invitation-token.js +1 -2
  39. package/dist-server/controllers/utils/save-invitation-token.js.map +1 -1
  40. package/dist-server/controllers/utils/save-verification-token.js +1 -2
  41. package/dist-server/controllers/utils/save-verification-token.js.map +1 -1
  42. package/dist-server/controllers/verification.js +3 -4
  43. package/dist-server/controllers/verification.js.map +1 -1
  44. package/dist-server/index.js.map +1 -1
  45. package/dist-server/middlewares/authenticate-401-middleware.js +2 -3
  46. package/dist-server/middlewares/authenticate-401-middleware.js.map +1 -1
  47. package/dist-server/middlewares/domain-authenticate-middleware.js +5 -3
  48. package/dist-server/middlewares/domain-authenticate-middleware.js.map +1 -1
  49. package/dist-server/middlewares/graphql-authenticate-middleware.js +1 -2
  50. package/dist-server/middlewares/graphql-authenticate-middleware.js.map +1 -1
  51. package/dist-server/middlewares/index.d.ts +1 -0
  52. package/dist-server/middlewares/index.js +3 -3
  53. package/dist-server/middlewares/index.js.map +1 -1
  54. package/dist-server/middlewares/jwt-authenticate-middleware.js +1 -2
  55. package/dist-server/middlewares/jwt-authenticate-middleware.js.map +1 -1
  56. package/dist-server/middlewares/signin-middleware.js +1 -2
  57. package/dist-server/middlewares/signin-middleware.js.map +1 -1
  58. package/dist-server/middlewares/webauthn-middleware.d.ts +1 -0
  59. package/dist-server/middlewares/webauthn-middleware.js +100 -0
  60. package/dist-server/middlewares/webauthn-middleware.js.map +1 -0
  61. package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
  62. package/dist-server/migrations/1566805283882-SeedPrivilege.js.map +1 -1
  63. package/dist-server/router/auth-checkin-router.js.map +1 -1
  64. package/dist-server/router/auth-private-process-router.js +7 -1
  65. package/dist-server/router/auth-private-process-router.js.map +1 -1
  66. package/dist-server/router/auth-public-process-router.js.map +1 -1
  67. package/dist-server/router/auth-signin-router.js.map +1 -1
  68. package/dist-server/router/auth-signup-router.js.map +1 -1
  69. package/dist-server/router/index.d.ts +1 -0
  70. package/dist-server/router/index.js +1 -0
  71. package/dist-server/router/index.js.map +1 -1
  72. package/dist-server/router/oauth2/oauth2-authorize-router.js.map +1 -1
  73. package/dist-server/router/oauth2/oauth2-router.js.map +1 -1
  74. package/dist-server/router/oauth2/oauth2-server.js.map +1 -1
  75. package/dist-server/router/oauth2/passport-oauth2-client-password.js +1 -2
  76. package/dist-server/router/oauth2/passport-oauth2-client-password.js.map +1 -1
  77. package/dist-server/router/oauth2/passport-refresh-token.js +1 -2
  78. package/dist-server/router/oauth2/passport-refresh-token.js.map +1 -1
  79. package/dist-server/router/site-root-router.js.map +1 -1
  80. package/dist-server/router/webauthn-router.d.ts +2 -0
  81. package/dist-server/router/webauthn-router.js +69 -0
  82. package/dist-server/router/webauthn-router.js.map +1 -0
  83. package/dist-server/routes.js +3 -1
  84. package/dist-server/routes.js.map +1 -1
  85. package/dist-server/service/app-binding/app-binding-mutation.js +2 -2
  86. package/dist-server/service/app-binding/app-binding-mutation.js.map +1 -1
  87. package/dist-server/service/app-binding/app-binding-query.js +3 -3
  88. package/dist-server/service/app-binding/app-binding-query.js.map +1 -1
  89. package/dist-server/service/app-binding/app-binding-types.js +2 -2
  90. package/dist-server/service/app-binding/app-binding-types.js.map +1 -1
  91. package/dist-server/service/app-binding/app-binding.js +2 -2
  92. package/dist-server/service/app-binding/app-binding.js.map +1 -1
  93. package/dist-server/service/appliance/appliance-mutation.js +2 -2
  94. package/dist-server/service/appliance/appliance-mutation.js.map +1 -1
  95. package/dist-server/service/appliance/appliance-query.d.ts +1 -0
  96. package/dist-server/service/appliance/appliance-query.js +24 -3
  97. package/dist-server/service/appliance/appliance-query.js.map +1 -1
  98. package/dist-server/service/appliance/appliance-types.js +6 -6
  99. package/dist-server/service/appliance/appliance-types.js.map +1 -1
  100. package/dist-server/service/appliance/appliance.d.ts +1 -1
  101. package/dist-server/service/appliance/appliance.js +3 -2
  102. package/dist-server/service/appliance/appliance.js.map +1 -1
  103. package/dist-server/service/application/application-mutation.js +2 -2
  104. package/dist-server/service/application/application-mutation.js.map +1 -1
  105. package/dist-server/service/application/application-query.js +3 -3
  106. package/dist-server/service/application/application-query.js.map +1 -1
  107. package/dist-server/service/application/application-types.js +8 -8
  108. package/dist-server/service/application/application-types.js.map +1 -1
  109. package/dist-server/service/application/application.js +7 -6
  110. package/dist-server/service/application/application.js.map +1 -1
  111. package/dist-server/service/auth-provider/auth-provider-mutation.js +2 -2
  112. package/dist-server/service/auth-provider/auth-provider-mutation.js.map +1 -1
  113. package/dist-server/service/auth-provider/auth-provider-parameter-spec.d.ts +3 -0
  114. package/dist-server/service/auth-provider/auth-provider-parameter-spec.js +6 -2
  115. package/dist-server/service/auth-provider/auth-provider-parameter-spec.js.map +1 -1
  116. package/dist-server/service/auth-provider/auth-provider-query.js +3 -3
  117. package/dist-server/service/auth-provider/auth-provider-query.js.map +1 -1
  118. package/dist-server/service/auth-provider/auth-provider-type.js +6 -6
  119. package/dist-server/service/auth-provider/auth-provider-type.js.map +1 -1
  120. package/dist-server/service/auth-provider/auth-provider.d.ts +0 -5
  121. package/dist-server/service/auth-provider/auth-provider.js +8 -22
  122. package/dist-server/service/auth-provider/auth-provider.js.map +1 -1
  123. package/dist-server/service/domain-generator/domain-generator-mutation.js +2 -2
  124. package/dist-server/service/domain-generator/domain-generator-mutation.js.map +1 -1
  125. package/dist-server/service/domain-generator/domain-generator-types.js +6 -6
  126. package/dist-server/service/domain-generator/domain-generator-types.js.map +1 -1
  127. package/dist-server/service/granted-role/granted-role-mutation.js +6 -6
  128. package/dist-server/service/granted-role/granted-role-mutation.js.map +1 -1
  129. package/dist-server/service/granted-role/granted-role-query.js +2 -2
  130. package/dist-server/service/granted-role/granted-role-query.js.map +1 -1
  131. package/dist-server/service/granted-role/granted-role.d.ts +1 -1
  132. package/dist-server/service/granted-role/granted-role.js +3 -3
  133. package/dist-server/service/granted-role/granted-role.js.map +1 -1
  134. package/dist-server/service/index.d.ts +2 -1
  135. package/dist-server/service/index.js +4 -1
  136. package/dist-server/service/index.js.map +1 -1
  137. package/dist-server/service/invitation/invitation-mutation.js +2 -2
  138. package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
  139. package/dist-server/service/invitation/invitation-query.js +2 -2
  140. package/dist-server/service/invitation/invitation-query.js.map +1 -1
  141. package/dist-server/service/invitation/invitation-types.js +2 -2
  142. package/dist-server/service/invitation/invitation-types.js.map +1 -1
  143. package/dist-server/service/invitation/invitation.js +2 -2
  144. package/dist-server/service/invitation/invitation.js.map +1 -1
  145. package/dist-server/service/login-history/login-history-query.js +3 -3
  146. package/dist-server/service/login-history/login-history-query.js.map +1 -1
  147. package/dist-server/service/login-history/login-history-type.js +2 -2
  148. package/dist-server/service/login-history/login-history-type.js.map +1 -1
  149. package/dist-server/service/login-history/login-history.d.ts +1 -1
  150. package/dist-server/service/login-history/login-history.js +4 -4
  151. package/dist-server/service/login-history/login-history.js.map +1 -1
  152. package/dist-server/service/partner/partner-mutation.js +2 -2
  153. package/dist-server/service/partner/partner-mutation.js.map +1 -1
  154. package/dist-server/service/partner/partner-query.js +4 -4
  155. package/dist-server/service/partner/partner-query.js.map +1 -1
  156. package/dist-server/service/partner/partner-types.js +2 -2
  157. package/dist-server/service/partner/partner-types.js.map +1 -1
  158. package/dist-server/service/partner/partner.d.ts +2 -2
  159. package/dist-server/service/partner/partner.js +6 -6
  160. package/dist-server/service/partner/partner.js.map +1 -1
  161. package/dist-server/service/password-history/password-history.js +2 -2
  162. package/dist-server/service/password-history/password-history.js.map +1 -1
  163. package/dist-server/service/privilege/privilege-directive.js.map +1 -1
  164. package/dist-server/service/privilege/privilege-mutation.js +2 -2
  165. package/dist-server/service/privilege/privilege-mutation.js.map +1 -1
  166. package/dist-server/service/privilege/privilege-query.js +3 -3
  167. package/dist-server/service/privilege/privilege-query.js.map +1 -1
  168. package/dist-server/service/privilege/privilege-types.js +8 -8
  169. package/dist-server/service/privilege/privilege-types.js.map +1 -1
  170. package/dist-server/service/privilege/privilege.js +6 -6
  171. package/dist-server/service/privilege/privilege.js.map +1 -1
  172. package/dist-server/service/role/role-mutation.js +2 -2
  173. package/dist-server/service/role/role-mutation.js.map +1 -1
  174. package/dist-server/service/role/role-query.js +3 -3
  175. package/dist-server/service/role/role-query.js.map +1 -1
  176. package/dist-server/service/role/role-types.js +10 -10
  177. package/dist-server/service/role/role-types.js.map +1 -1
  178. package/dist-server/service/role/role.d.ts +1 -1
  179. package/dist-server/service/role/role.js +4 -3
  180. package/dist-server/service/role/role.js.map +1 -1
  181. package/dist-server/service/user/domain-query.js +2 -2
  182. package/dist-server/service/user/domain-query.js.map +1 -1
  183. package/dist-server/service/user/user-mutation.js +2 -2
  184. package/dist-server/service/user/user-mutation.js.map +1 -1
  185. package/dist-server/service/user/user-query.js +3 -32
  186. package/dist-server/service/user/user-query.js.map +1 -1
  187. package/dist-server/service/user/user-types.js +6 -6
  188. package/dist-server/service/user/user-types.js.map +1 -1
  189. package/dist-server/service/user/user.d.ts +2 -0
  190. package/dist-server/service/user/user.js +19 -29
  191. package/dist-server/service/user/user.js.map +1 -1
  192. package/dist-server/service/users-auth-providers/users-auth-providers.js +3 -3
  193. package/dist-server/service/users-auth-providers/users-auth-providers.js.map +1 -1
  194. package/dist-server/service/verification-token/verification-token.js +3 -3
  195. package/dist-server/service/verification-token/verification-token.js.map +1 -1
  196. package/dist-server/service/web-auth-credential/index.d.ts +2 -0
  197. package/dist-server/service/web-auth-credential/index.js +6 -0
  198. package/dist-server/service/web-auth-credential/index.js.map +1 -0
  199. package/dist-server/service/web-auth-credential/web-auth-credential.d.ts +15 -0
  200. package/dist-server/service/web-auth-credential/web-auth-credential.js +72 -0
  201. package/dist-server/service/web-auth-credential/web-auth-credential.js.map +1 -0
  202. package/dist-server/templates/account-unlock-email.js +1 -2
  203. package/dist-server/templates/account-unlock-email.js.map +1 -1
  204. package/dist-server/templates/invitation-email.js +1 -2
  205. package/dist-server/templates/invitation-email.js.map +1 -1
  206. package/dist-server/templates/reset-password-email.js +1 -2
  207. package/dist-server/templates/reset-password-email.js.map +1 -1
  208. package/dist-server/templates/verification-email.js +1 -2
  209. package/dist-server/templates/verification-email.js.map +1 -1
  210. package/dist-server/tsconfig.tsbuildinfo +1 -1
  211. package/dist-server/types.d.ts +2 -2
  212. package/dist-server/types.js.map +1 -1
  213. package/dist-server/utils/accepts.js +1 -2
  214. package/dist-server/utils/accepts.js.map +1 -1
  215. package/dist-server/utils/access-token-cookie.d.ts +1 -0
  216. package/dist-server/utils/access-token-cookie.js +14 -4
  217. package/dist-server/utils/access-token-cookie.js.map +1 -1
  218. package/dist-server/utils/check-permission.js +1 -2
  219. package/dist-server/utils/check-permission.js.map +1 -1
  220. package/dist-server/utils/check-user-belongs-domain.js +1 -2
  221. package/dist-server/utils/check-user-belongs-domain.js.map +1 -1
  222. package/dist-server/utils/encrypt-state.js +2 -3
  223. package/dist-server/utils/encrypt-state.js.map +1 -1
  224. package/dist-server/utils/get-aes-256-key.js.map +1 -1
  225. package/dist-server/utils/get-domain-from-hostname.js +1 -2
  226. package/dist-server/utils/get-domain-from-hostname.js.map +1 -1
  227. package/dist-server/utils/get-domain-users.js +2 -3
  228. package/dist-server/utils/get-domain-users.js.map +1 -1
  229. package/dist-server/utils/get-secret.js.map +1 -1
  230. package/dist-server/utils/get-user-domains.js +4 -5
  231. package/dist-server/utils/get-user-domains.js.map +1 -1
  232. package/helps/config/SECRET.ja.md +13 -0
  233. package/helps/config/SECRET.ko.md +13 -0
  234. package/helps/config/SECRET.md +3 -3
  235. package/helps/config/SECRET.ms.md +13 -0
  236. package/helps/config/SECRET.zh.md +13 -0
  237. package/helps/config/accessTokenCookieKey.ja.md +11 -0
  238. package/helps/config/accessTokenCookieKey.ko.md +11 -0
  239. package/helps/config/accessTokenCookieKey.md +1 -1
  240. package/helps/config/accessTokenCookieKey.ms.md +11 -0
  241. package/helps/config/accessTokenCookieKey.zh.md +11 -0
  242. package/helps/config/applianceJwtExpiresIn.ja.md +26 -0
  243. package/helps/config/applianceJwtExpiresIn.ko.md +26 -0
  244. package/helps/config/applianceJwtExpiresIn.md +18 -15
  245. package/helps/config/applianceJwtExpiresIn.ms.md +30 -0
  246. package/helps/config/applianceJwtExpiresIn.zh.md +26 -0
  247. package/helps/config/disableUserSignupProcess.ja.md +22 -0
  248. package/helps/config/disableUserSignupProcess.ko.md +22 -0
  249. package/helps/config/disableUserSignupProcess.md +3 -3
  250. package/helps/config/disableUserSignupProcess.ms.md +22 -0
  251. package/helps/config/disableUserSignupProcess.zh.md +22 -0
  252. package/helps/config/i18n.ja.md +44 -0
  253. package/helps/config/i18n.ko.md +44 -0
  254. package/helps/config/i18n.md +6 -6
  255. package/helps/config/i18n.ms.md +44 -0
  256. package/helps/config/i18n.zh.md +44 -0
  257. package/helps/config/password.ja.md +53 -0
  258. package/helps/config/password.ko.md +65 -0
  259. package/helps/config/password.md +8 -36
  260. package/helps/config/password.ms.md +65 -0
  261. package/helps/config/password.zh.md +65 -0
  262. package/helps/config/publicHomeRoute.ja.md +14 -0
  263. package/helps/config/publicHomeRoute.ko.md +14 -0
  264. package/helps/config/publicHomeRoute.md +3 -3
  265. package/helps/config/publicHomeRoute.ms.md +14 -0
  266. package/helps/config/publicHomeRoute.zh.md +14 -0
  267. package/helps/config/session.ja.md +45 -0
  268. package/helps/config/session.ko.md +49 -0
  269. package/helps/config/session.md +10 -10
  270. package/helps/config/session.ms.md +46 -0
  271. package/helps/config/session.zh.md +49 -0
  272. package/package.json +12 -9
  273. package/server/constants/error-code.ts +3 -0
  274. package/server/middlewares/authenticate-401-middleware.ts +1 -1
  275. package/server/middlewares/domain-authenticate-middleware.ts +5 -1
  276. package/server/middlewares/index.ts +2 -1
  277. package/server/middlewares/webauthn-middleware.ts +127 -0
  278. package/server/router/auth-private-process-router.ts +8 -1
  279. package/server/router/index.ts +1 -0
  280. package/server/router/webauthn-router.ts +87 -0
  281. package/server/routes.ts +7 -8
  282. package/server/service/app-binding/app-binding-query.ts +1 -1
  283. package/server/service/appliance/appliance-query.ts +22 -1
  284. package/server/service/appliance/appliance.ts +4 -3
  285. package/server/service/application/application-query.ts +1 -1
  286. package/server/service/application/application.ts +7 -6
  287. package/server/service/auth-provider/auth-provider-parameter-spec.ts +3 -0
  288. package/server/service/auth-provider/auth-provider-query.ts +4 -1
  289. package/server/service/auth-provider/auth-provider-type.ts +3 -7
  290. package/server/service/auth-provider/auth-provider.ts +3 -19
  291. package/server/service/granted-role/granted-role.ts +2 -2
  292. package/server/service/index.ts +5 -5
  293. package/server/service/login-history/login-history-query.ts +4 -1
  294. package/server/service/login-history/login-history.ts +3 -3
  295. package/server/service/partner/partner-query.ts +5 -2
  296. package/server/service/partner/partner.ts +6 -6
  297. package/server/service/privilege/privilege-query.ts +14 -3
  298. package/server/service/role/role-query.ts +1 -1
  299. package/server/service/role/role.ts +3 -2
  300. package/server/service/user/user-query.ts +1 -33
  301. package/server/service/user/user.ts +12 -22
  302. package/server/service/users-auth-providers/users-auth-providers.ts +1 -1
  303. package/server/service/web-auth-credential/index.ts +3 -0
  304. package/server/service/web-auth-credential/web-auth-credential.ts +67 -0
  305. package/server/types.ts +2 -2
  306. package/server/utils/access-token-cookie.ts +12 -0
  307. package/translations/en.json +33 -28
  308. package/translations/ja.json +34 -29
  309. package/translations/ko.json +35 -29
  310. package/translations/ms.json +5 -0
  311. package/translations/zh.json +6 -0
@@ -0,0 +1,87 @@
1
+ import Router from 'koa-router'
2
+ import { getRepository } from '@things-factory/shell'
3
+ import { appPackage } from '@things-factory/env'
4
+
5
+ import { generateRegistrationOptions, generateAuthenticationOptions } from '@simplewebauthn/server'
6
+
7
+ import { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'
8
+ import {
9
+ PublicKeyCredentialCreationOptionsJSON,
10
+ } from '@simplewebauthn/server/script/deps'
11
+ import { setAccessTokenCookie } from '../utils/access-token-cookie'
12
+ import { createWebAuthnMiddleware } from '../middlewares/webauthn-middleware';
13
+
14
+ export const webAuthnGlobalPublicRouter = new Router()
15
+ export const webAuthnGlobalPrivateRouter = new Router()
16
+
17
+ const { name: rpName } = appPackage as any
18
+
19
+ webAuthnGlobalPrivateRouter.get('/auth/register-webauthn/challenge', async (context, next) => {
20
+ const { user } = context.state
21
+ const rpID = context.hostname
22
+
23
+ const webAuthCredentials = await getRepository(WebAuthCredential).find({
24
+ where: {
25
+ user: { id: user.id }
26
+ }
27
+ })
28
+
29
+ const options: PublicKeyCredentialCreationOptionsJSON = await generateRegistrationOptions({
30
+ rpName,
31
+ rpID,
32
+ userName: user.email,
33
+ userDisplayName: user.name,
34
+ // Don't prompt users for additional information about the authenticator
35
+ // (Recommended for smoother UX)
36
+ attestationType: 'none',
37
+ // Prevent users from re-registering existing authenticators
38
+ excludeCredentials: webAuthCredentials.map(credential => ({
39
+ id: credential.credentialId
40
+ // Optional
41
+ // transports: credential.transports
42
+ })),
43
+ authenticatorSelection: {
44
+ // Defaults
45
+ residentKey: 'preferred',
46
+ userVerification: 'preferred',
47
+ // Optional
48
+ authenticatorAttachment: 'platform'
49
+ }
50
+ })
51
+
52
+ context.session.challenge = options.challenge
53
+ context.body = options
54
+ })
55
+
56
+ webAuthnGlobalPrivateRouter.post('/auth/verify-registration', createWebAuthnMiddleware('webauthn-register'));
57
+
58
+ webAuthnGlobalPublicRouter.get('/auth/signin-webauthn/challenge', async (context, next) => {
59
+ const rpID = context.hostname
60
+
61
+ const options = await generateAuthenticationOptions({
62
+ rpID,
63
+ userVerification: 'preferred'
64
+ })
65
+
66
+ context.session.challenge = options.challenge
67
+ context.body = options
68
+ })
69
+
70
+ webAuthnGlobalPublicRouter.post(
71
+ '/auth/signin-webauthn', createWebAuthnMiddleware('webauthn-login'),
72
+ async (context, next) => {
73
+ const { domain, user } = context. state
74
+ const { request } = context
75
+ const { body: reqBody } = request
76
+
77
+ const token = await user.sign({ subdomain: domain?.subdomain })
78
+ setAccessTokenCookie(context, token)
79
+
80
+ var redirectURL = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(reqBody.redirectTo || '/')}`
81
+
82
+ /* 2단계 인터렉션 때문에 브라우저에서 fetch(...)로 진행될 것이므로, redirect(3xx) 응답으로 처리할 수 없다. 따라서, 데이타로 redirectURL를 응답한다. */
83
+ context.body = { redirectURL, verified: true }
84
+
85
+ await next();
86
+ }
87
+ )
package/server/routes.ts CHANGED
@@ -10,11 +10,12 @@ import {
10
10
  oauth2AuthorizeRouter,
11
11
  oauth2Router,
12
12
  pathBaseDomainRouter,
13
- siteRootRouter
13
+ siteRootRouter,
14
+ webAuthnGlobalPublicRouter,
15
+ webAuthnGlobalPrivateRouter
14
16
  } from './router'
15
17
 
16
18
  import { setAccessTokenCookie } from './utils/access-token-cookie'
17
- import { User } from './service/user/user'
18
19
 
19
20
  const isPathBaseDomain = !config.get('subdomain') && !config.get('useVirtualHostBasedDomain')
20
21
 
@@ -27,7 +28,7 @@ process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRout
27
28
  authSigninRouter.get('/auth/sso-signin', app.ssoMiddlewares[0], async context => {
28
29
  const { user } = context.state
29
30
 
30
- const token = user.sign()
31
+ const token = await user.sign()
31
32
  setAccessTokenCookie(context, token)
32
33
 
33
34
  context.redirect('/auth/checkin')
@@ -41,12 +42,14 @@ process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRo
41
42
  /* globalPrivateRouter based nested-routers */
42
43
  globalPrivateRouter.use(authCheckinRouter.routes(), authCheckinRouter.allowedMethods())
43
44
  globalPrivateRouter.use(authPrivateProcessRouter.routes(), authPrivateProcessRouter.allowedMethods())
45
+ globalPrivateRouter.use(webAuthnGlobalPrivateRouter.routes(), webAuthnGlobalPrivateRouter.allowedMethods())
44
46
  })
45
47
 
46
48
  process.on('bootstrap-module-domain-public-route' as any, (app, domainPublicRouter) => {
47
49
  /* domainPublicRouter based nested-routers */
48
50
  domainPublicRouter.use(authSigninRouter.routes(), authSigninRouter.allowedMethods())
49
51
  domainPublicRouter.use(authSignupRouter.routes(), authSignupRouter.allowedMethods())
52
+ domainPublicRouter.use(webAuthnGlobalPublicRouter.routes(), webAuthnGlobalPublicRouter.allowedMethods())
50
53
 
51
54
  /* path '/admin/oauth/...' is deprecated. should use path '/oauth/...' for oauth2 related routing */
52
55
  domainPublicRouter.use('/oauth', oauth2Router.routes(), oauth2Router.allowedMethods()) // if i use context
@@ -61,11 +64,7 @@ process.on('bootstrap-module-domain-private-route' as any, (app, domainPrivateRo
61
64
  // pathBaseDomainRouter는 history-fallback의 경우에 인증 처리를 하기 위한 라우터이다.
62
65
  // (보통, URL 링크등을 통해서 domain path URL로 바로 요청하는 경우에 해당한다.)
63
66
  // pathBaseDomainRouter는 domain path를 domain-private-router를 사용하는 것을 전제로 한다.
64
- domainPrivateRouter.use(
65
- '/domain/:domain/oauth',
66
- oauth2AuthorizeRouter.routes(),
67
- oauth2AuthorizeRouter.allowedMethods()
68
- )
67
+ domainPrivateRouter.use('/domain/:domain/oauth', oauth2AuthorizeRouter.routes(), oauth2AuthorizeRouter.allowedMethods())
69
68
  domainPrivateRouter.use('/domain', pathBaseDomainRouter.routes(), pathBaseDomainRouter.allowedMethods())
70
69
  }
71
70
 
@@ -22,7 +22,7 @@ export class AppBindingQuery {
22
22
 
23
23
  /* TODO optimize query */
24
24
  @Query(returns => AppBindingList)
25
- async appBindings(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<UserList> {
25
+ async appBindings(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<UserList> {
26
26
  const { domain } = context.state
27
27
 
28
28
  // const convertedParams = convertListParams(params)
@@ -17,7 +17,28 @@ export class ApplianceQuery {
17
17
 
18
18
  @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
19
19
  @Query(returns => ApplianceList, { description: 'To fetch multiple appliance' })
20
- async appliances(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ApplianceList> {
20
+ async appliances(
21
+ @Args(type => ListParam) params: ListParam,
22
+ @Ctx() context: ResolverContext
23
+ ): Promise<ApplianceList> {
24
+ const { domain } = context.state
25
+
26
+ const queryBuilder = getQueryBuilderFromListParams({
27
+ domain,
28
+ params,
29
+ repository: getRepository(Appliance),
30
+ alias: 'appliance',
31
+ searchables: ['name', 'description']
32
+ })
33
+
34
+ const [items, total] = await queryBuilder.getManyAndCount()
35
+
36
+ return { items, total }
37
+ }
38
+
39
+ @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
40
+ @Query(returns => ApplianceList, { description: 'To fetch multiple appliance' })
41
+ async edges(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<ApplianceList> {
21
42
  const { domain } = context.state
22
43
 
23
44
  const queryBuilder = getQueryBuilderFromListParams({
@@ -30,7 +30,8 @@ export class Appliance {
30
30
  readonly id: string
31
31
 
32
32
  @ManyToOne(type => Domain)
33
- domain: Domain
33
+ @Field(type => Domain)
34
+ domain?: Domain
34
35
 
35
36
  @RelationId((appliance: Appliance) => appliance.domain)
36
37
  domainId: string
@@ -71,8 +72,8 @@ export class Appliance {
71
72
  DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
72
73
  ? 'longtext'
73
74
  : DATABASE_TYPE == 'oracle'
74
- ? 'clob'
75
- : 'varchar'
75
+ ? 'clob'
76
+ : 'varchar'
76
77
  })
77
78
  @Field({ nullable: true })
78
79
  @Directive('@privilege(category: "security", privilege: "query", domainOwnerGranted: true)')
@@ -24,7 +24,7 @@ export class ApplicationQuery {
24
24
 
25
25
  @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
26
26
  @Query(returns => ApplicationList, { description: 'To fetch multiple application' })
27
- async applications(@Args() params: ListParam, @Ctx() context: ResolverContext) {
27
+ async applications(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext) {
28
28
  const { domain } = context.state
29
29
 
30
30
  const queryBuilder = getQueryBuilderFromListParams({
@@ -54,6 +54,7 @@ export class Application {
54
54
  readonly id?: string
55
55
 
56
56
  @ManyToOne(type => Domain)
57
+ @Field(type => Domain)
57
58
  domain?: Domain
58
59
 
59
60
  @RelationId((application: Application) => application.domain)
@@ -97,8 +98,8 @@ export class Application {
97
98
  DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
98
99
  ? 'longtext'
99
100
  : DATABASE_TYPE == 'oracle'
100
- ? 'clob'
101
- : 'varchar'
101
+ ? 'clob'
102
+ : 'varchar'
102
103
  })
103
104
  @Field({ nullable: true })
104
105
  @Directive('@privilege(category: "security", privilege: "query", domainOwnerGranted: true)')
@@ -113,8 +114,8 @@ export class Application {
113
114
  DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
114
115
  ? 'enum'
115
116
  : DATABASE_TYPE == 'oracle'
116
- ? 'varchar2'
117
- : 'smallint',
117
+ ? 'varchar2'
118
+ : 'smallint',
118
119
  enum: ApplicationType,
119
120
  default: ApplicationType.OTHERS
120
121
  })
@@ -130,14 +131,14 @@ export class Application {
130
131
  updatedAt?: Date
131
132
 
132
133
  @ManyToOne(type => User, { nullable: true })
133
- @Field({ nullable: true })
134
+ @Field(type => User, { nullable: true })
134
135
  creator?: User
135
136
 
136
137
  @RelationId((application: Application) => application.creator)
137
138
  creatorId?: string
138
139
 
139
140
  @ManyToOne(type => User, { nullable: true })
140
- @Field({ nullable: true })
141
+ @Field(type => User, { nullable: true })
141
142
  updater?: User
142
143
 
143
144
  @RelationId((application: Application) => application.updater)
@@ -18,4 +18,7 @@ export class AuthProviderParameterSpec {
18
18
 
19
19
  @Field(type => ScalarObject, { nullable: true })
20
20
  property?: { [key: string]: any }
21
+
22
+ @Field(type => ScalarObject, { nullable: true })
23
+ styles?: { [key: string]: any }
21
24
  }
@@ -25,7 +25,10 @@ export class AuthProviderQuery {
25
25
 
26
26
  @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
27
27
  @Query(returns => AuthProviderList, { description: 'To fetch multiple AuthProviders' })
28
- async authProviders(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<AuthProviderList> {
28
+ async authProviders(
29
+ @Args(type => ListParam) params: ListParam,
30
+ @Ctx() context: ResolverContext
31
+ ): Promise<AuthProviderList> {
29
32
  const { domain } = context.state
30
33
 
31
34
  const queryBuilder = getQueryBuilderFromListParams({
@@ -1,11 +1,7 @@
1
- import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'
2
- import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
3
- import { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'
1
+ import { ObjectType, Field, InputType, Int, ID } from 'type-graphql'
4
2
 
5
- import { ObjectRef, ScalarObject } from '@things-factory/shell'
6
-
7
- import { AuthProvider, AuthProviderStatus } from './auth-provider'
8
- import { AuthProviderParameterSpec } from './auth-provider-parameter-spec'
3
+ import { ScalarObject } from '@things-factory/shell'
4
+ import { AuthProvider } from './auth-provider'
9
5
 
10
6
  @InputType()
11
7
  export class NewAuthProvider {
@@ -1,17 +1,15 @@
1
1
  import {
2
2
  CreateDateColumn,
3
3
  UpdateDateColumn,
4
- DeleteDateColumn,
5
4
  Entity,
6
5
  Index,
7
6
  Column,
8
7
  RelationId,
9
8
  ManyToOne,
10
9
  OneToMany,
11
- PrimaryGeneratedColumn,
12
- VersionColumn
10
+ PrimaryGeneratedColumn
13
11
  } from 'typeorm'
14
- import { Directive, ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'
12
+ import { Directive, ObjectType, Field, Int, ID } from 'type-graphql'
15
13
 
16
14
  import { Domain, ScalarObject, encryptTransformer } from '@things-factory/shell'
17
15
  import { User } from '../user/user'
@@ -30,16 +28,6 @@ export type AuthProviderRegistry = {
30
28
  [type: string]: AuthProviderImpl
31
29
  }
32
30
 
33
- export enum AuthProviderStatus {
34
- STATUS_A = 'STATUS_A',
35
- STATUS_B = 'STATUS_B'
36
- }
37
-
38
- registerEnumType(AuthProviderStatus, {
39
- name: 'AuthProviderStatus',
40
- description: 'state enumeration of a authProvider'
41
- })
42
-
43
31
  @ObjectType()
44
32
  export class AuthProviderType {
45
33
  @Field()
@@ -75,7 +63,7 @@ export class AuthProvider {
75
63
  readonly id: string
76
64
 
77
65
  @ManyToOne(type => Domain)
78
- @Field({ nullable: true })
66
+ @Field(type => Domain)
79
67
  domain?: Domain
80
68
 
81
69
  @RelationId((authProvider: AuthProvider) => authProvider.domain)
@@ -89,10 +77,6 @@ export class AuthProvider {
89
77
  @Field({ nullable: true })
90
78
  active?: boolean
91
79
 
92
- @Column({ nullable: true })
93
- @Field({ nullable: true })
94
- state?: AuthProviderStatus
95
-
96
80
  @Directive('@privilege(category: "security", privilege: "query", domainOwnerGranted: true)')
97
81
  @Column({ nullable: true })
98
82
  @Field({ nullable: true })
@@ -19,8 +19,8 @@ export class GrantedRole {
19
19
  roleId: string
20
20
 
21
21
  @ManyToOne(type => Domain)
22
- @Field()
23
- domain: Domain
22
+ @Field(type => Domain)
23
+ domain?: Domain
24
24
 
25
25
  @RelationId((grantedRole: GrantedRole) => grantedRole.domain)
26
26
  domainId: string
@@ -1,8 +1,5 @@
1
1
  /* IMPORT ENTITIES AND RESOLVERS */
2
- import {
3
- entities as UsersAuthProvidersEntities,
4
- resolvers as UsersAuthProvidersResolvers
5
- } from './users-auth-providers'
2
+ import { entities as UsersAuthProvidersEntities, resolvers as UsersAuthProvidersResolvers } from './users-auth-providers'
6
3
  import { entities as AuthProviderEntities, resolvers as AuthProviderResolvers } from './auth-provider'
7
4
  import { resolvers as AppbindingResolver } from './app-binding'
8
5
  import { entities as ApplianceEntities, resolvers as ApplianceResolvers } from './appliance'
@@ -18,6 +15,7 @@ import { privilegeDirectiveResolver, privilegeDirectiveTypeDefs } from './privil
18
15
  import { entities as RoleEntities, resolvers as RoleResolvers } from './role'
19
16
  import { entities as UserEntities, resolvers as UserResolvers } from './user'
20
17
  import { entities as VerificationTokenEntities } from './verification-token'
18
+ import { entities as WebAuthCredentialEntities } from './web-auth-credential'
21
19
 
22
20
  /* EXPORT ENTITY TYPES */
23
21
  export * from './users-auth-providers/users-auth-providers'
@@ -34,6 +32,7 @@ export * from './app-binding/app-binding'
34
32
  export * from './password-history/password-history'
35
33
  export * from './verification-token/verification-token'
36
34
  export * from './login-history/login-history'
35
+ export * from './web-auth-credential/web-auth-credential'
37
36
 
38
37
  /* EXPORT TYPES */
39
38
  export * from './app-binding/app-binding-types'
@@ -60,7 +59,8 @@ export const entities = [
60
59
  ...InvitationEntities,
61
60
  ...PasswordHistoryEntities,
62
61
  ...VerificationTokenEntities,
63
- ...LoginHistoryEntities
62
+ ...LoginHistoryEntities,
63
+ ...WebAuthCredentialEntities
64
64
  ]
65
65
 
66
66
  export const schema = {
@@ -9,7 +9,10 @@ import { LoginHistoryList } from './login-history-type'
9
9
  @Resolver(LoginHistory)
10
10
  export class LoginHistoryQuery {
11
11
  @Query(returns => LoginHistoryList, { description: 'To fetch multiple LoginHistories' })
12
- async loginHistories(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<LoginHistoryList> {
12
+ async loginHistories(
13
+ @Args(type => ListParam) params: ListParam,
14
+ @Ctx() context: ResolverContext
15
+ ): Promise<LoginHistoryList> {
13
16
  const { domain } = context.state
14
17
 
15
18
  const queryBuilder = getQueryBuilderFromListParams({
@@ -14,14 +14,14 @@ export class LoginHistory {
14
14
  readonly id: string
15
15
 
16
16
  @ManyToOne(type => Domain)
17
- @Field()
18
- accessDomain: Domain
17
+ @Field(type => Domain)
18
+ accessDomain?: Domain
19
19
 
20
20
  @RelationId((loginHistory: LoginHistory) => loginHistory.accessDomain)
21
21
  accessDomainId: string
22
22
 
23
23
  @ManyToOne(type => User)
24
- @Field()
24
+ @Field(type => User)
25
25
  accessUser: User
26
26
 
27
27
  @RelationId((loginHistory: LoginHistory) => loginHistory.accessUser)
@@ -12,7 +12,7 @@ import { PartnerList } from './partner-types'
12
12
  export class PartnerQuery {
13
13
  @Directive('@privilege(category: "partner", privilege: "query", domainOwnerGranted: true)')
14
14
  @Query(returns => PartnerList)
15
- async partners(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<PartnerList> {
15
+ async partners(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<PartnerList> {
16
16
  if (await checkUserBelongsDomain(context.state.domain, context.state.user)) {
17
17
  const { domain } = context.state
18
18
 
@@ -45,7 +45,10 @@ export class PartnerQuery {
45
45
 
46
46
  @Directive('@privilege(category: "partner", privilege: "query")')
47
47
  @Query(returns => DomainList)
48
- async searchCustomers(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<DomainList> {
48
+ async searchCustomers(
49
+ @Args(type => ListParam) params: ListParam,
50
+ @Ctx() context: ResolverContext
51
+ ): Promise<DomainList> {
49
52
  const { domain } = context.state
50
53
  const partners: Partner[] = await getRepository(Partner).find({
51
54
  where: { domain: { id: domain.id } },
@@ -20,25 +20,25 @@ export class Partner {
20
20
  readonly id: string
21
21
 
22
22
  @ManyToOne(type => Domain)
23
- @Field()
24
- domain: Domain
23
+ @Field(type => Domain)
24
+ domain?: Domain
25
25
 
26
26
  @RelationId((partner: Partner) => partner.domain)
27
27
  domainId: string
28
28
 
29
29
  @ManyToOne(type => Domain)
30
- @Field()
31
- partnerDomain: Domain
30
+ @Field(type => Domain)
31
+ partnerDomain?: Domain
32
32
 
33
33
  @RelationId((partner: Partner) => partner.partnerDomain)
34
34
  partnerDomainId: string
35
35
 
36
36
  @CreateDateColumn()
37
- @Field()
37
+ @Field({ nullable: true })
38
38
  requestedAt: Date
39
39
 
40
40
  @UpdateDateColumn()
41
- @Field()
41
+ @Field({ nullable: true })
42
42
  approvedAt: Date
43
43
 
44
44
  @ManyToOne(type => User, { nullable: true })
@@ -10,7 +10,10 @@ import { PrivilegeList } from './privilege-types'
10
10
  export class PrivilegeQuery {
11
11
  @Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
12
12
  @Query(returns => PrivilegeList, { description: 'To fetch multiple privileges' })
13
- async privileges(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<PrivilegeList> {
13
+ async privileges(
14
+ @Args(type => ListParam) params: ListParam,
15
+ @Ctx() context: ResolverContext
16
+ ): Promise<PrivilegeList> {
14
17
  const [items, total] = await getQueryBuilderFromListParams({
15
18
  params,
16
19
  repository: getRepository(Privilege),
@@ -29,13 +32,21 @@ export class PrivilegeQuery {
29
32
  }
30
33
 
31
34
  @Query(returns => Boolean, { description: 'To query whether I have the given permission' })
32
- async hasPrivilege(@Arg('privilege') privilege: string, @Arg('category') category: string, @Ctx() context: ResolverContext): Promise<Boolean> {
35
+ async hasPrivilege(
36
+ @Arg('privilege') privilege: string,
37
+ @Arg('category') category: string,
38
+ @Ctx() context: ResolverContext
39
+ ): Promise<Boolean> {
33
40
  const { domain, user } = context.state
34
41
  return await User.hasPrivilege(privilege, category, domain, user)
35
42
  }
36
43
 
37
44
  @Query(returns => [Domain], { description: 'To fetch domains with given privilege for user' })
38
- async domainsWithPrivilege(@Arg('privilege') privilege: string, @Arg('category') category: string, @Ctx() context: ResolverContext): Promise<Partial<Domain>[]> {
45
+ async domainsWithPrivilege(
46
+ @Arg('privilege') privilege: string,
47
+ @Arg('category') category: string,
48
+ @Ctx() context: ResolverContext
49
+ ): Promise<Partial<Domain>[]> {
39
50
  const { user } = context.state
40
51
  return await User.getDomainsWithPrivilege(privilege, category, user)
41
52
  }
@@ -24,7 +24,7 @@ export class RoleQuery {
24
24
 
25
25
  @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
26
26
  @Query(returns => RoleList, { description: 'To fetch multiple users' })
27
- async roles(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<RoleList> {
27
+ async roles(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<RoleList> {
28
28
  const { domain } = context.state
29
29
 
30
30
  const [items, total] = await getQueryBuilderFromListParams({
@@ -24,13 +24,14 @@ export class Role {
24
24
  readonly id: string
25
25
 
26
26
  @ManyToOne(type => Domain)
27
- domain: Domain
27
+ @Field(type => Domain)
28
+ domain?: Domain
28
29
 
29
30
  @RelationId((role: Role) => role.domain)
30
31
  domainId: string
31
32
 
32
33
  @Column()
33
- @Field()
34
+ @Field({ nullable: true })
34
35
  name: string
35
36
 
36
37
  @ManyToMany(type => User, user => user.roles)
@@ -27,7 +27,7 @@ export class UserQuery {
27
27
 
28
28
  @Directive('@privilege(category: "user", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
29
29
  @Query(returns => UserList, { description: 'To fetch multiple users' })
30
- async users(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<UserList> {
30
+ async users(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<UserList> {
31
31
  const { domain } = context.state
32
32
 
33
33
  const qb = getQueryBuilderFromListParams({
@@ -83,38 +83,6 @@ export class UserQuery {
83
83
  return Boolean(defaultPassword)
84
84
  }
85
85
 
86
- // @Query(returns => [User], { description: '...' })
87
- // async domainUsers(@Ctx() context: ResolverContext): Promise<User[]> {
88
- // const { domain } = context.state
89
-
90
- // const qb: SelectQueryBuilder<User> = buildDomainUsersQueryBuilder(domain.id, 'USER')
91
- // const domainUsers: User[] = await qb
92
- // .orWhere(qb => {
93
- // const subQuery = qb
94
- // .subQuery()
95
- // .select('CAST(APPLICATION.id as TEXT)')
96
- // .from(Application, 'APPLICATION')
97
- // .where('APPLICATION.domain_id = :domainId', { domainId: domain.id })
98
- // .getQuery()
99
- // return 'USER.reference IN ' + subQuery
100
- // })
101
- // .orWhere(qb => {
102
- // const subQuery = qb
103
- // .subQuery()
104
- // .select('CAST(APPLIANCE.id as TEXT)')
105
- // .from(Appliance, 'APPLIANCE')
106
- // .where('APPLIANCE.domain_id = :domainId', { domainId: domain.id })
107
- // .getQuery()
108
- // return 'USER.reference IN ' + subQuery
109
- // })
110
- // .getMany()
111
-
112
- // return domainUsers.map((user: User & { owner: boolean }) => {
113
- // user.owner = user.id === domain.owner
114
- // return user
115
- // })
116
- // }
117
-
118
86
  @Directive('@privilege(category: "user", privilege: "query")')
119
87
  @Query(returns => Boolean, { description: '...' })
120
88
  async checkUserExistence(@Arg('email', type => GraphQLEmailAddress) email: string): Promise<Boolean> {