@things-factory/auth-base 8.0.0-alpha.28 → 8.0.0-alpha.35

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 (85) hide show
  1. package/dist-client/tsconfig.tsbuildinfo +1 -1
  2. package/dist-server/constants/error-code.d.ts +2 -0
  3. package/dist-server/constants/error-code.js +3 -1
  4. package/dist-server/constants/error-code.js.map +1 -1
  5. package/dist-server/controllers/change-pwd.js +2 -2
  6. package/dist-server/controllers/change-pwd.js.map +1 -1
  7. package/dist-server/controllers/delete-user.js +13 -12
  8. package/dist-server/controllers/delete-user.js.map +1 -1
  9. package/dist-server/controllers/invitation.d.ts +2 -1
  10. package/dist-server/controllers/invitation.js +30 -5
  11. package/dist-server/controllers/invitation.js.map +1 -1
  12. package/dist-server/controllers/profile.d.ts +4 -3
  13. package/dist-server/controllers/profile.js +20 -2
  14. package/dist-server/controllers/profile.js.map +1 -1
  15. package/dist-server/controllers/signin.d.ts +4 -1
  16. package/dist-server/controllers/signin.js +17 -1
  17. package/dist-server/controllers/signin.js.map +1 -1
  18. package/dist-server/controllers/signup.js +13 -4
  19. package/dist-server/controllers/signup.js.map +1 -1
  20. package/dist-server/controllers/unlock-user.js +1 -0
  21. package/dist-server/controllers/unlock-user.js.map +1 -1
  22. package/dist-server/controllers/verification.js +1 -0
  23. package/dist-server/controllers/verification.js.map +1 -1
  24. package/dist-server/middlewares/signin-middleware.js +3 -3
  25. package/dist-server/middlewares/signin-middleware.js.map +1 -1
  26. package/dist-server/migrations/1548206416130-SeedUser.js +2 -1
  27. package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
  28. package/dist-server/router/auth-checkin-router.js +8 -2
  29. package/dist-server/router/auth-checkin-router.js.map +1 -1
  30. package/dist-server/router/auth-private-process-router.js +12 -7
  31. package/dist-server/router/auth-private-process-router.js.map +1 -1
  32. package/dist-server/router/auth-public-process-router.js +14 -5
  33. package/dist-server/router/auth-public-process-router.js.map +1 -1
  34. package/dist-server/router/auth-signin-router.js +3 -3
  35. package/dist-server/router/auth-signin-router.js.map +1 -1
  36. package/dist-server/service/invitation/invitation-mutation.d.ts +3 -2
  37. package/dist-server/service/invitation/invitation-mutation.js +20 -8
  38. package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
  39. package/dist-server/service/user/user-mutation.d.ts +3 -2
  40. package/dist-server/service/user/user-mutation.js +62 -37
  41. package/dist-server/service/user/user-mutation.js.map +1 -1
  42. package/dist-server/service/user/user-types.d.ts +1 -0
  43. package/dist-server/service/user/user-types.js +4 -0
  44. package/dist-server/service/user/user-types.js.map +1 -1
  45. package/dist-server/service/user/user.d.ts +1 -0
  46. package/dist-server/service/user/user.js +40 -14
  47. package/dist-server/service/user/user.js.map +1 -1
  48. package/dist-server/templates/account-unlock-email.d.ts +2 -1
  49. package/dist-server/templates/account-unlock-email.js +1 -1
  50. package/dist-server/templates/account-unlock-email.js.map +1 -1
  51. package/dist-server/templates/invitation-email.d.ts +2 -1
  52. package/dist-server/templates/invitation-email.js +1 -1
  53. package/dist-server/templates/invitation-email.js.map +1 -1
  54. package/dist-server/templates/verification-email.d.ts +2 -1
  55. package/dist-server/templates/verification-email.js +1 -1
  56. package/dist-server/templates/verification-email.js.map +1 -1
  57. package/dist-server/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +5 -5
  59. package/server/constants/error-code.ts +2 -0
  60. package/server/controllers/change-pwd.ts +3 -2
  61. package/server/controllers/delete-user.ts +16 -13
  62. package/server/controllers/invitation.ts +36 -5
  63. package/server/controllers/profile.ts +29 -2
  64. package/server/controllers/signin.ts +21 -2
  65. package/server/controllers/signup.ts +16 -4
  66. package/server/controllers/unlock-user.ts +1 -0
  67. package/server/controllers/verification.ts +1 -0
  68. package/server/middlewares/signin-middleware.ts +3 -3
  69. package/server/migrations/1548206416130-SeedUser.ts +2 -1
  70. package/server/router/auth-checkin-router.ts +11 -5
  71. package/server/router/auth-private-process-router.ts +14 -7
  72. package/server/router/auth-public-process-router.ts +16 -5
  73. package/server/router/auth-signin-router.ts +3 -3
  74. package/server/service/invitation/invitation-mutation.ts +24 -9
  75. package/server/service/user/user-mutation.ts +68 -36
  76. package/server/service/user/user-types.ts +3 -0
  77. package/server/service/user/user.ts +41 -14
  78. package/server/templates/account-unlock-email.ts +1 -1
  79. package/server/templates/invitation-email.ts +1 -1
  80. package/server/templates/verification-email.ts +1 -1
  81. package/translations/en.json +4 -1
  82. package/translations/ja.json +4 -1
  83. package/translations/ko.json +5 -3
  84. package/translations/ms.json +4 -1
  85. package/translations/zh.json +4 -1
@@ -18,12 +18,12 @@ const SSOLinks = Object.values(SSOConfig)
18
18
  });
19
19
  exports.authSigninRouter = new koa_router_1.default();
20
20
  exports.authSigninRouter.get('/auth/signin', async (context, next) => {
21
- const { redirect_to, email } = context.query;
21
+ const { redirect_to, username } = context.query;
22
22
  await context.render('auth-page', {
23
23
  pageElement: 'auth-signin',
24
24
  elementScript: '/auth/signin.js',
25
25
  data: {
26
- email,
26
+ username,
27
27
  redirectTo: redirect_to,
28
28
  ssoLinks: SSOLinks,
29
29
  disableUserSignupProcess,
@@ -34,7 +34,7 @@ exports.authSigninRouter.get('/auth/signin', async (context, next) => {
34
34
  });
35
35
  exports.authSigninRouter.post('/auth/signin', middlewares_1.signinMiddleware, async (context, next) => {
36
36
  const { request, t } = context;
37
- const { token, user, domain } = context.state;
37
+ const { token, domain } = context.state;
38
38
  const { body: reqBody, header } = request;
39
39
  if (!(0, accepts_1.accepts)(header.accept, ['text/html', '*/*'])) {
40
40
  context.body = token;
@@ -1 +1 @@
1
- {"version":3,"file":"auth-signin-router.js","sourceRoot":"","sources":["../../server/router/auth-signin-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,6CAA4C;AAC5C,gDAAiD;AACjD,8CAA0C;AAC1C,sEAAmE;AAEnE,MAAM,wBAAwB,GAAG,YAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;AAC9E,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AAErD,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAS,CAAC,CAAA;AAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;KACtC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC;KAC1C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACxB,CAAC,CAAC,CAAA;AAES,QAAA,gBAAgB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAE5C,wBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC3D,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAE5C,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;QAChC,WAAW,EAAE,aAAa;QAC1B,aAAa,EAAE,iBAAiB;QAChC,IAAI,EAAE;YACJ,KAAK;YACL,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,QAAQ;YAClB,wBAAwB;YACxB,0BAA0B;YAC1B,SAAS;SACV;KACF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,wBAAgB,CAAC,IAAI,CAAC,cAAc,EAAE,8BAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC9E,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;IAC9B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAC7C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAEzC,IAAI,CAAC,IAAA,iBAAO,EAAC,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,IAAI,GAAG,KAAK,CAAA;QACpB,OAAM;IACR,CAAC;IAED,IAAI,UAAU,GAAG,gBAAgB,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,kBAAkB,CACrG,OAAO,CAAC,UAAU,IAAI,GAAG,CAC1B,EAAE,CAAA;IAEH,IAAA,0CAAoB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA","sourcesContent":["import Router from 'koa-router'\n\nimport { config } from '@things-factory/env'\nimport { signinMiddleware } from '../middlewares'\nimport { accepts } from '../utils/accepts'\nimport { setAccessTokenCookie } from '../utils/access-token-cookie'\n\nconst disableUserSignupProcess = config.get('disableUserSignupProcess', false)\nconst disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)\nconst languages = config.get('i18n/languages', false)\n\nconst SSOConfig = config.get('sso', {} as any)\nconst SSOLinks = Object.values(SSOConfig)\n .filter(({ link, title }) => link && title)\n .map(({ link, title }) => {\n return { link, title }\n })\n\nexport const authSigninRouter = new Router()\n\nauthSigninRouter.get('/auth/signin', async (context, next) => {\n const { redirect_to, email } = context.query\n\n await context.render('auth-page', {\n pageElement: 'auth-signin',\n elementScript: '/auth/signin.js',\n data: {\n email,\n redirectTo: redirect_to,\n ssoLinks: SSOLinks,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n})\n\nauthSigninRouter.post('/auth/signin', signinMiddleware, async (context, next) => {\n const { request, t } = context\n const { token, user, domain } = context.state\n const { body: reqBody, header } = request\n\n if (!accepts(header.accept, ['text/html', '*/*'])) {\n context.body = token\n return\n }\n\n var redirectTo = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(\n reqBody.redirectTo || '/'\n )}`\n\n setAccessTokenCookie(context, token)\n\n context.redirect(redirectTo)\n})\n"]}
1
+ {"version":3,"file":"auth-signin-router.js","sourceRoot":"","sources":["../../server/router/auth-signin-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,6CAA4C;AAC5C,gDAAiD;AACjD,8CAA0C;AAC1C,sEAAmE;AAEnE,MAAM,wBAAwB,GAAG,YAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;AAC9E,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AAErD,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAS,CAAC,CAAA;AAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;KACtC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC;KAC1C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;IACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACxB,CAAC,CAAC,CAAA;AAES,QAAA,gBAAgB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAE5C,wBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC3D,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAE/C,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;QAChC,WAAW,EAAE,aAAa;QAC1B,aAAa,EAAE,iBAAiB;QAChC,IAAI,EAAE;YACJ,QAAQ;YACR,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,QAAQ;YAClB,wBAAwB;YACxB,0BAA0B;YAC1B,SAAS;SACV;KACF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,wBAAgB,CAAC,IAAI,CAAC,cAAc,EAAE,8BAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC9E,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;IAC9B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IACvC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAEzC,IAAI,CAAC,IAAA,iBAAO,EAAC,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,IAAI,GAAG,KAAK,CAAA;QACpB,OAAM;IACR,CAAC;IAED,IAAI,UAAU,GAAG,gBAAgB,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,kBAAkB,CACrG,OAAO,CAAC,UAAU,IAAI,GAAG,CAC1B,EAAE,CAAA;IAEH,IAAA,0CAAoB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA","sourcesContent":["import Router from 'koa-router'\n\nimport { config } from '@things-factory/env'\nimport { signinMiddleware } from '../middlewares'\nimport { accepts } from '../utils/accepts'\nimport { setAccessTokenCookie } from '../utils/access-token-cookie'\n\nconst disableUserSignupProcess = config.get('disableUserSignupProcess', false)\nconst disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)\nconst languages = config.get('i18n/languages', false)\n\nconst SSOConfig = config.get('sso', {} as any)\nconst SSOLinks = Object.values(SSOConfig)\n .filter(({ link, title }) => link && title)\n .map(({ link, title }) => {\n return { link, title }\n })\n\nexport const authSigninRouter = new Router()\n\nauthSigninRouter.get('/auth/signin', async (context, next) => {\n const { redirect_to, username } = context.query\n\n await context.render('auth-page', {\n pageElement: 'auth-signin',\n elementScript: '/auth/signin.js',\n data: {\n username,\n redirectTo: redirect_to,\n ssoLinks: SSOLinks,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n})\n\nauthSigninRouter.post('/auth/signin', signinMiddleware, async (context, next) => {\n const { request, t } = context\n const { token, domain } = context.state\n const { body: reqBody, header } = request\n\n if (!accepts(header.accept, ['text/html', '*/*'])) {\n context.body = token\n return\n }\n\n var redirectTo = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(\n reqBody.redirectTo || '/'\n )}`\n\n setAccessTokenCookie(context, token)\n\n context.redirect(redirectTo)\n})\n"]}
@@ -1,3 +1,4 @@
1
+ import { User } from '../../service/user/user';
1
2
  import { Invitation } from './invitation';
2
3
  export declare class InvitationMutation {
3
4
  cancelInvitation(email: string, reference: string, type: string): Promise<boolean>;
@@ -5,12 +6,12 @@ export declare class InvitationMutation {
5
6
  email: string;
6
7
  reference: string;
7
8
  type: string;
8
- creator: import("..").User;
9
- updater: import("..").User;
9
+ updater: User;
10
10
  id: string;
11
11
  token: string;
12
12
  createdAt: Date;
13
13
  updatedAt: Date;
14
+ creator: User;
14
15
  creatorId: string;
15
16
  updaterId: string;
16
17
  } & Invitation>;
@@ -2,9 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InvitationMutation = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
5
6
  const type_graphql_1 = require("type-graphql");
6
7
  const graphql_scalars_1 = require("graphql-scalars");
7
8
  const shell_1 = require("@things-factory/shell");
9
+ const user_1 = require("../../service/user/user");
8
10
  const invitation_1 = require("../../controllers/invitation");
9
11
  const invitation_2 = require("./invitation");
10
12
  let InvitationMutation = class InvitationMutation {
@@ -18,26 +20,36 @@ let InvitationMutation = class InvitationMutation {
18
20
  return true;
19
21
  }
20
22
  async sendInvitation(email, reference, type, context) {
21
- const repository = (0, shell_1.getRepository)(invitation_2.Invitation);
22
- const oldone = await repository.findOneBy({
23
- email,
24
- type,
25
- reference
23
+ const { user: updater } = context.state;
24
+ const invitationRepository = (0, shell_1.getRepository)(invitation_2.Invitation);
25
+ var user = await (0, shell_1.getRepository)(user_1.User).findOne({
26
+ where: {
27
+ email: (0, typeorm_1.ILike)(email),
28
+ status: user_1.UserStatus.ACTIVATED
29
+ }
26
30
  });
27
- // TODO send invitation
31
+ if (!user) {
32
+ throw new Error(`user not found: ${email}`);
33
+ }
28
34
  await (0, invitation_1.sendInvitationEmail)({
29
35
  invitation: {
30
36
  email,
31
37
  reference,
32
38
  type
33
39
  },
40
+ user,
34
41
  context
35
42
  });
43
+ const oldone = await invitationRepository.findOneBy({
44
+ email,
45
+ type,
46
+ reference
47
+ });
36
48
  // update or create
37
- return await repository.save(Object.assign(Object.assign({}, oldone), { // take only id from oldone for update
49
+ return await invitationRepository.save(Object.assign(Object.assign({ creator: updater }, oldone), { // take only id from oldone for update
38
50
  email,
39
51
  reference,
40
- type, creator: context.state.user, updater: context.state.user }));
52
+ type, updater: updater }));
41
53
  }
42
54
  };
43
55
  exports.InvitationMutation = InvitationMutation;
@@ -1 +1 @@
1
- {"version":3,"file":"invitation-mutation.js","sourceRoot":"","sources":["../../../server/service/invitation/invitation-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAA2D;AAC3D,qDAAqD;AAErD,iDAAqD;AAErD,6DAAkE;AAClE,6CAAyC;AAGlC,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAEvB,AAAN,KAAK,CAAC,gBAAgB,CACuB,KAAa,EACtC,SAAiB,EACtB,IAAY;QAEzB,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,uBAAU,CAAC,CAAA;QAE5C,MAAM,UAAU,CAAC,MAAM,CAAC;YACtB,KAAK;YACL,SAAS;YACT,IAAI;SACL,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAGK,AAAN,KAAK,CAAC,cAAc,CACyB,KAAa,EACtC,SAAiB,EACtB,IAAY,EAClB,OAAwB;QAE/B,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,uBAAU,CAAC,CAAA;QAE5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC;YACxC,KAAK;YACL,IAAI;YACJ,SAAS;SACV,CAAC,CAAA;QAEF,uBAAuB;QACvB,MAAM,IAAA,gCAAmB,EAAC;YACxB,UAAU,EAAE;gBACV,KAAK;gBACL,SAAS;gBACT,IAAI;aACL;YACD,OAAO;SACR,CAAC,CAAA;QAEF,mBAAmB;QACnB,OAAO,MAAM,UAAU,CAAC,IAAI,iCACvB,MAAM,KAAE,sCAAsC;YACjD,KAAK;YACL,SAAS;YACT,IAAI,EACJ,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAC3B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,IAC3B,CAAA;IACJ,CAAC;CACF,CAAA;AArDY,gDAAkB;AAEvB;IADL,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;IAE1B,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,qCAAmB,CAAC,CAAA;IACzC,mBAAA,IAAA,kBAAG,EAAC,WAAW,CAAC,CAAA;IAChB,mBAAA,IAAA,kBAAG,EAAC,MAAM,CAAC,CAAA;;;;0DAWb;AAGK;IADL,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,uBAAU,CAAC;IAE7B,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,qCAAmB,CAAC,CAAA;IACzC,mBAAA,IAAA,kBAAG,EAAC,WAAW,CAAC,CAAA;IAChB,mBAAA,IAAA,kBAAG,EAAC,MAAM,CAAC,CAAA;IACX,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;wDA6BP;6BApDU,kBAAkB;IAD9B,IAAA,uBAAQ,EAAC,uBAAU,CAAC;GACR,kBAAkB,CAqD9B","sourcesContent":["import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { sendInvitationEmail } from '../../controllers/invitation'\nimport { Invitation } from './invitation'\n\n@Resolver(Invitation)\nexport class InvitationMutation {\n @Mutation(returns => Boolean)\n async cancelInvitation(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('reference') reference: string,\n @Arg('type') type: string\n ) {\n const repository = getRepository(Invitation)\n\n await repository.delete({\n email,\n reference,\n type\n })\n\n return true\n }\n\n @Mutation(returns => Invitation)\n async sendInvitation(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('reference') reference: string,\n @Arg('type') type: string,\n @Ctx() context: ResolverContext\n ) {\n const repository = getRepository(Invitation)\n\n const oldone = await repository.findOneBy({\n email,\n type,\n reference\n })\n\n // TODO send invitation\n await sendInvitationEmail({\n invitation: {\n email,\n reference,\n type\n },\n context\n })\n\n // update or create\n return await repository.save({\n ...oldone, // take only id from oldone for update\n email,\n reference,\n type,\n creator: context.state.user,\n updater: context.state.user\n })\n }\n}\n"]}
1
+ {"version":3,"file":"invitation-mutation.js","sourceRoot":"","sources":["../../../server/service/invitation/invitation-mutation.ts"],"names":[],"mappings":";;;;AAAA,qCAA+B;AAE/B,+CAA2D;AAC3D,qDAAqD;AAErD,iDAAqD;AAErD,kDAA0D;AAC1D,6DAAkE;AAClE,6CAAyC;AAGlC,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAEvB,AAAN,KAAK,CAAC,gBAAgB,CACuB,KAAa,EACtC,SAAiB,EACtB,IAAY;QAEzB,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,uBAAU,CAAC,CAAA;QAE5C,MAAM,UAAU,CAAC,MAAM,CAAC;YACtB,KAAK;YACL,SAAS;YACT,IAAI;SACL,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAGK,AAAN,KAAK,CAAC,cAAc,CACyB,KAAa,EACtC,SAAiB,EACtB,IAAY,EAClB,OAAwB;QAE/B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACvC,MAAM,oBAAoB,GAAG,IAAA,qBAAa,EAAC,uBAAU,CAAC,CAAA;QAEtD,IAAI,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,WAAI,CAAC,CAAC,OAAO,CAAC;YAC3C,KAAK,EAAE;gBACL,KAAK,EAAE,IAAA,eAAK,EAAC,KAAK,CAAC;gBACnB,MAAM,EAAE,iBAAU,CAAC,SAAS;aAC7B;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAA;QAC7C,CAAC;QAED,MAAM,IAAA,gCAAmB,EAAC;YACxB,UAAU,EAAE;gBACV,KAAK;gBACL,SAAS;gBACT,IAAI;aACL;YACD,IAAI;YACJ,OAAO;SACR,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,SAAS,CAAC;YAClD,KAAK;YACL,IAAI;YACJ,SAAS;SACV,CAAC,CAAA;QAEF,mBAAmB;QACnB,OAAO,MAAM,oBAAoB,CAAC,IAAI,+BACpC,OAAO,EAAE,OAAO,IACb,MAAM,KAAE,sCAAsC;YACjD,KAAK;YACL,SAAS;YACT,IAAI,EACJ,OAAO,EAAE,OAAO,IAChB,CAAA;IACJ,CAAC;CACF,CAAA;AAjEY,gDAAkB;AAEvB;IADL,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;IAE1B,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,qCAAmB,CAAC,CAAA;IACzC,mBAAA,IAAA,kBAAG,EAAC,WAAW,CAAC,CAAA;IAChB,mBAAA,IAAA,kBAAG,EAAC,MAAM,CAAC,CAAA;;;;0DAWb;AAGK;IADL,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,uBAAU,CAAC;IAE7B,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,qCAAmB,CAAC,CAAA;IACzC,mBAAA,IAAA,kBAAG,EAAC,WAAW,CAAC,CAAA;IAChB,mBAAA,IAAA,kBAAG,EAAC,MAAM,CAAC,CAAA;IACX,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;wDAyCP;6BAhEU,kBAAkB;IAD9B,IAAA,uBAAQ,EAAC,uBAAU,CAAC;GACR,kBAAkB,CAiE9B","sourcesContent":["import { ILike } from 'typeorm'\n\nimport { Arg, Ctx, Mutation, Resolver } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { User, UserStatus } from '../../service/user/user'\nimport { sendInvitationEmail } from '../../controllers/invitation'\nimport { Invitation } from './invitation'\n\n@Resolver(Invitation)\nexport class InvitationMutation {\n @Mutation(returns => Boolean)\n async cancelInvitation(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('reference') reference: string,\n @Arg('type') type: string\n ) {\n const repository = getRepository(Invitation)\n\n await repository.delete({\n email,\n reference,\n type\n })\n\n return true\n }\n\n @Mutation(returns => Invitation)\n async sendInvitation(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('reference') reference: string,\n @Arg('type') type: string,\n @Ctx() context: ResolverContext\n ) {\n const { user: updater } = context.state\n const invitationRepository = getRepository(Invitation)\n\n var user = await getRepository(User).findOne({\n where: {\n email: ILike(email),\n status: UserStatus.ACTIVATED\n }\n })\n\n if (!user) {\n throw new Error(`user not found: ${email}`)\n }\n\n await sendInvitationEmail({\n invitation: {\n email,\n reference,\n type\n },\n user,\n context\n })\n\n const oldone = await invitationRepository.findOneBy({\n email,\n type,\n reference\n })\n\n // update or create\n return await invitationRepository.save({\n creator: updater,\n ...oldone, // take only id from oldone for update\n email,\n reference,\n type,\n updater: updater\n })\n }\n}\n"]}
@@ -9,6 +9,7 @@ export declare class UserMutation {
9
9
  salt: string;
10
10
  passwordUpdatedAt: Date;
11
11
  password: string;
12
+ username: string;
12
13
  name: string;
13
14
  description?: string;
14
15
  email: string;
@@ -18,8 +19,8 @@ export declare class UserMutation {
18
19
  } & User>;
19
20
  updateUser(email: string, patch: UserPatch, context: ResolverContext): Promise<any>;
20
21
  updateMultipleUser(patches: UserPatch[], context: ResolverContext): Promise<any[]>;
21
- deleteUser(email: string, context: ResolverContext): Promise<boolean>;
22
- deleteUsers(emails: string[], context: ResolverContext): Promise<boolean>;
22
+ deleteUser(username: string, context: ResolverContext): Promise<boolean>;
23
+ deleteUsers(usernames: string[], context: ResolverContext): Promise<boolean>;
23
24
  inviteUser(email: string, context: ResolverContext): Promise<boolean>;
24
25
  deleteDomainUser(email: string, context: ResolverContext): Promise<boolean>;
25
26
  transferOwner(email: string, context: ResolverContext): Promise<boolean>;
@@ -12,32 +12,41 @@ const get_domain_users_1 = require("../../utils/get-domain-users");
12
12
  const role_1 = require("../role/role");
13
13
  const user_1 = require("./user");
14
14
  const user_types_1 = require("./user-types");
15
+ const error_code_1 = require("../../constants/error-code");
15
16
  let UserMutation = class UserMutation {
16
17
  async createUser(user, context) {
17
- const { domain } = context.state;
18
+ const { domain, tx } = context.state;
18
19
  const { defaultPassword } = env_1.config.get('password');
19
- const { email } = user;
20
+ const { username, email } = user;
21
+ const userRepository = (0, shell_1.getRepository)(user_1.User, tx);
22
+ user.username = username.trim();
20
23
  user.email = email.trim();
21
- const oldUser = await (0, shell_1.getRepository)(user_1.User).findOne({ where: { email: (0, typeorm_1.ILike)(user.email) } });
22
- if (oldUser) {
23
- throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: 'operato' }));
24
+ if (await userRepository.findOne({ where: { username: user.username } })) {
25
+ throw new Error(context.t(error_code_1.USERNAME_ALREADY_EXISTS));
26
+ }
27
+ if (await userRepository.findOne({ where: { email: (0, typeorm_1.ILike)(user.email) } })) {
28
+ throw new Error(context.t(error_code_1.EMAIL_ALREADY_EXISTS));
24
29
  }
25
30
  if (!user.password && !defaultPassword) {
26
- throw new Error(context.t('error.initial password or default password should be supported'));
31
+ throw new Error('initial password or default password should be supported.');
32
+ }
33
+ // TODO username은 다음 패턴을 따라야 한다. pattern="^[A-Za-z0-9]*$"
34
+ if (!/^[A-Za-z0-9]*$/.test(user.username)) {
35
+ throw new Error(context.t('error.invalid x', { x: context.t('field.username') }));
27
36
  }
28
37
  // consider if validation password rule is required
29
38
  /* check if password is following the rule */
30
39
  // User.validatePasswordByRule(user.password, context.lng)
31
40
  const salt = user_1.User.generateSalt();
32
- return await (0, shell_1.getRepository)(user_1.User).save(Object.assign(Object.assign({ creator: context.state.user, updater: context.state.user }, user), { domains: [domain], roles: user.roles && user.roles.length
33
- ? await (0, shell_1.getRepository)(role_1.Role).findBy({
41
+ return await userRepository.save(Object.assign(Object.assign({ creator: context.state.user, updater: context.state.user }, user), { domains: [domain], roles: user.roles && user.roles.length
42
+ ? await (0, shell_1.getRepository)(role_1.Role, tx).findBy({
34
43
  id: (0, typeorm_1.In)(user.roles.map(role => role.id)),
35
44
  domain: { id: domain.id }
36
45
  })
37
46
  : [], salt, passwordUpdatedAt: new Date(), password: user.password ? user_1.User.encode(user.password, salt) : user_1.User.encode(defaultPassword, salt) }));
38
47
  }
39
48
  async updateUser(email, patch, context) {
40
- const { domain, user: updater } = context.state;
49
+ const { domain, user: updater, tx } = context.state;
41
50
  const qb = (0, get_domain_users_1.buildDomainUsersQueryBuilder)(domain.id, 'USER');
42
51
  const user = await qb
43
52
  .andWhere('LOWER(USER.email) = :email', { email: (email === null || email === void 0 ? void 0 : email.toLowerCase().trim()) || '' })
@@ -45,16 +54,18 @@ let UserMutation = class UserMutation {
45
54
  .leftJoinAndSelect('ROLES.domain', 'R_DOMAIN')
46
55
  .getOne();
47
56
  if (patch.roles) {
48
- patch.roles = await (0, shell_1.getRepository)(role_1.Role).find({ where: { id: (0, typeorm_1.In)(patch.roles.map((r) => r.id)) } });
57
+ patch.roles = await (0, shell_1.getRepository)(role_1.Role, tx).find({
58
+ where: { id: (0, typeorm_1.In)(patch.roles.map((r) => r.id)) }
59
+ });
49
60
  }
50
61
  if (patch.status && patch.status === 'activated') {
51
62
  user.status = user_1.UserStatus.ACTIVATED;
52
63
  }
53
- return await (0, shell_1.getRepository)(user_1.User).save(Object.assign(Object.assign(Object.assign({}, user), patch), { updater }));
64
+ return await (0, shell_1.getRepository)(user_1.User, tx).save(Object.assign(Object.assign(Object.assign({}, user), patch), { updater }));
54
65
  }
55
66
  async updateMultipleUser(patches, context) {
56
67
  const { domain, user, tx } = context.state;
57
- const userRepo = tx.getRepository(user_1.User);
68
+ const userRepo = (0, shell_1.getRepository)(user_1.User, tx);
58
69
  let results = [];
59
70
  const _createRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === '+');
60
71
  const _updateRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === 'M');
@@ -113,19 +124,19 @@ let UserMutation = class UserMutation {
113
124
  }
114
125
  return results;
115
126
  }
116
- async deleteUser(email, context) {
127
+ async deleteUser(username, context) {
117
128
  const { tx } = context.state;
118
- await (0, delete_user_1.deleteUser)({ email }, tx);
129
+ await (0, delete_user_1.deleteUser)({ username }, tx);
119
130
  return true;
120
131
  }
121
- async deleteUsers(emails, context) {
132
+ async deleteUsers(usernames, context) {
122
133
  const { tx } = context.state;
123
- await (0, delete_user_1.deleteUsers)({ emails }, tx);
134
+ await (0, delete_user_1.deleteUsers)({ usernames }, tx);
124
135
  return true;
125
136
  }
126
137
  async inviteUser(email, context) {
127
- const { domain } = context.state;
128
- const invitee = await (0, shell_1.getRepository)(user_1.User).findOne({
138
+ const { domain, tx } = context.state;
139
+ const invitee = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
129
140
  where: { email: (0, typeorm_1.ILike)(email) },
130
141
  relations: ['domains']
131
142
  });
@@ -137,14 +148,15 @@ let UserMutation = class UserMutation {
137
148
  throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }));
138
149
  }
139
150
  invitee.domains = [...existingDomains, domain];
140
- await (0, shell_1.getRepository)(user_1.User).save(invitee);
151
+ await (0, shell_1.getRepository)(user_1.User, tx).save(invitee);
141
152
  return true;
142
153
  }
143
154
  async deleteDomainUser(email, context) {
144
155
  const { tx, domain } = context.state;
145
- let user = await tx
146
- .getRepository(user_1.User)
147
- .findOne({ where: { email: (0, typeorm_1.ILike)(email) }, relations: ['domains', 'roles', 'roles.domain'] });
156
+ let user = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
157
+ where: { email: (0, typeorm_1.ILike)(email) },
158
+ relations: ['domains', 'roles', 'roles.domain']
159
+ });
148
160
  if (!user) {
149
161
  throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }));
150
162
  }
@@ -156,22 +168,35 @@ let UserMutation = class UserMutation {
156
168
  user.domains.splice(targetDomainIdx, 1);
157
169
  // Remove domain's roles that user has
158
170
  user.roles = user.roles.filter((role) => role.domain.id !== domain.id);
159
- await tx.getRepository(user_1.User).save(user);
171
+ await (0, shell_1.getRepository)(user_1.User, tx).save(user);
160
172
  return true;
161
173
  }
162
174
  async transferOwner(email, context) {
163
- const { domain } = context.state;
164
- const user = await (0, shell_1.getRepository)(user_1.User).findOne({
165
- where: { email: (0, typeorm_1.ILike)(email) }
175
+ const { domain, tx } = context.state;
176
+ const user = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
177
+ where: { email: (0, typeorm_1.ILike)(email) },
178
+ relations: ['domains', 'roles']
166
179
  });
180
+ if (!user) {
181
+ throw new Error('Failed to find user');
182
+ }
183
+ if (user.status !== user_1.UserStatus.ACTIVATED) {
184
+ throw new Error('Only activated users are eligible to receive admin privileges.');
185
+ }
186
+ if (user.domains.map((d) => d.id).indexOf(domain.id) < 0) {
187
+ throw new Error(`User is not belongs to current domain`);
188
+ }
189
+ if (user.roles.filter((r) => r.domainId == domain.id).length == 0) {
190
+ throw new Error(`Only users with at least one role in this domain are eligible to receive admin privileges.`);
191
+ }
167
192
  domain.owner = user.id;
168
- await (0, shell_1.getRepository)(shell_1.Domain).save(domain);
193
+ await (0, shell_1.getRepository)(shell_1.Domain, tx).save(domain);
169
194
  return true;
170
195
  }
171
196
  async activateUser(userId, context) {
172
197
  var _a;
173
198
  const { tx, domain } = context.state;
174
- const targetUser = await tx.getRepository(user_1.User).findOne({
199
+ const targetUser = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
175
200
  where: { id: userId },
176
201
  relations: ['domains']
177
202
  });
@@ -183,13 +208,13 @@ let UserMutation = class UserMutation {
183
208
  }
184
209
  targetUser.failCount = 0;
185
210
  targetUser.status = user_1.UserStatus.ACTIVATED;
186
- await tx.getRepository(user_1.User).save(targetUser);
211
+ await (0, shell_1.getRepository)(user_1.User, tx).save(targetUser);
187
212
  return true;
188
213
  }
189
214
  async inactivateUser(userId, context) {
190
215
  var _a;
191
216
  const { tx, domain } = context.state;
192
- const targetUser = await tx.getRepository(user_1.User).findOne({
217
+ const targetUser = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
193
218
  where: { id: userId },
194
219
  relations: ['domains']
195
220
  });
@@ -203,7 +228,7 @@ let UserMutation = class UserMutation {
203
228
  throw new Error('Admin deactivation not allowed');
204
229
  }
205
230
  targetUser.status = user_1.UserStatus.INACTIVE;
206
- await tx.getRepository(user_1.User).save(targetUser);
231
+ await (0, shell_1.getRepository)(user_1.User, tx).save(targetUser);
207
232
  return true;
208
233
  }
209
234
  async resetPasswordToDefault(userId, context) {
@@ -213,7 +238,7 @@ let UserMutation = class UserMutation {
213
238
  if (!defaultPassword) {
214
239
  throw new Error('No default password found');
215
240
  }
216
- const targetUser = await tx.getRepository(user_1.User).findOne({
241
+ const targetUser = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
217
242
  where: { id: userId },
218
243
  relations: ['domains']
219
244
  });
@@ -225,12 +250,12 @@ let UserMutation = class UserMutation {
225
250
  }
226
251
  targetUser.salt = user_1.User.generateSalt();
227
252
  targetUser.password = user_1.User.encode(defaultPassword, targetUser.salt);
228
- await tx.getRepository(user_1.User).save(targetUser);
253
+ await (0, shell_1.getRepository)(user_1.User, tx).save(targetUser);
229
254
  return true;
230
255
  }
231
256
  async updateUserRoles(userId, availableRoles, selectedRoles, context) {
232
257
  const { domain, tx } = context.state;
233
- let user = await tx.getRepository(user_1.User).findOne({
258
+ let user = await (0, shell_1.getRepository)(user_1.User, tx).findOne({
234
259
  where: { id: userId },
235
260
  relations: ['domains', 'roles']
236
261
  });
@@ -243,7 +268,7 @@ let UserMutation = class UserMutation {
243
268
  const availableRoleIds = availableRoles.map((r) => r.id);
244
269
  user.roles = user.roles.filter((r) => availableRoleIds.indexOf(r.id) < 0);
245
270
  user.roles = user.roles.concat(selectedRoles);
246
- return await tx.getRepository(user_1.User).save(user);
271
+ return await (0, shell_1.getRepository)(user_1.User, tx).save(user);
247
272
  }
248
273
  };
249
274
  exports.UserMutation = UserMutation;
@@ -282,7 +307,7 @@ tslib_1.__decorate([
282
307
  (0, type_graphql_1.Directive)('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)'),
283
308
  (0, type_graphql_1.Directive)('@transaction'),
284
309
  (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete a user' }),
285
- tslib_1.__param(0, (0, type_graphql_1.Arg)('email', type => graphql_scalars_1.GraphQLEmailAddress)),
310
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('username')),
286
311
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
287
312
  tslib_1.__metadata("design:type", Function),
288
313
  tslib_1.__metadata("design:paramtypes", [String, Object]),
@@ -292,7 +317,7 @@ tslib_1.__decorate([
292
317
  (0, type_graphql_1.Directive)('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)'),
293
318
  (0, type_graphql_1.Directive)('@transaction'),
294
319
  (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete some users' }),
295
- tslib_1.__param(0, (0, type_graphql_1.Arg)('emails', type => [String])),
320
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('usernames', type => [String])),
296
321
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
297
322
  tslib_1.__metadata("design:type", Function),
298
323
  tslib_1.__metadata("design:paramtypes", [Array, Object]),
@@ -1 +1 @@
1
- {"version":3,"file":"user-mutation.js","sourceRoot":"","sources":["../../../server/service/user/user-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { ILike, In, SelectQueryBuilder } from 'typeorm'\n\nimport { config } from '@things-factory/env'\nimport { Domain, getRepository, ObjectRef } from '@things-factory/shell'\n\nimport { deleteUser as commonDeleteUser, deleteUsers as commonDeleteUsers } from '../../controllers/delete-user'\nimport { buildDomainUsersQueryBuilder } from '../../utils/get-domain-users'\nimport { Role } from '../role/role'\nimport { User, UserStatus } from './user'\nimport { NewUser, UserPatch } from './user-types'\n\n@Resolver(User)\nexport class UserMutation {\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To create new user' })\n async createUser(@Arg('user') user: NewUser, @Ctx() context: ResolverContext) {\n const { domain } = context.state\n const { defaultPassword } = config.get('password')\n const { email } = user\n\n user.email = email.trim()\n\n const oldUser: User = await getRepository(User).findOne({ where: { email: ILike(user.email) } })\n if (oldUser) {\n throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: 'operato' }))\n }\n\n if (!user.password && !defaultPassword) {\n throw new Error(context.t('error.initial password or default password should be supported'))\n }\n\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(user.password, context.lng)\n\n const salt = User.generateSalt()\n\n return await getRepository(User).save({\n creator: context.state.user,\n updater: context.state.user,\n ...user,\n domains: [domain],\n roles:\n user.roles && user.roles.length\n ? await getRepository(Role).findBy({\n id: In(user.roles.map(role => role.id)),\n domain: { id: domain.id }\n })\n : [],\n salt,\n passwordUpdatedAt: new Date(),\n password: user.password ? User.encode(user.password, salt) : User.encode(defaultPassword, salt)\n })\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To modify user information' })\n async updateUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('patch') patch: UserPatch,\n @Ctx() context: ResolverContext\n ) {\n const { domain, user: updater }: { domain: Domain; user: User } = context.state\n const qb: SelectQueryBuilder<User> = buildDomainUsersQueryBuilder(domain.id, 'USER')\n const user: User = await qb\n .andWhere('LOWER(USER.email) = :email', { email: email?.toLowerCase().trim() || '' })\n .leftJoinAndSelect('USER.roles', 'ROLES')\n .leftJoinAndSelect('ROLES.domain', 'R_DOMAIN')\n .getOne()\n\n if (patch.roles) {\n patch.roles = await getRepository(Role).find({ where: { id: In(patch.roles.map((r: Partial<Role>) => r.id)) } })\n }\n\n if (patch.status && patch.status === 'activated') {\n user.status = UserStatus.ACTIVATED\n }\n\n return await getRepository(User).save({\n ...user,\n ...patch,\n updater\n } as any)\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => [User], { description: 'To modify multiple users information' })\n async updateMultipleUser(@Arg('patches', type => [UserPatch]) patches: UserPatch[], @Ctx() context: ResolverContext) {\n const { domain, user, tx } = context.state\n const userRepo = tx.getRepository(User)\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(newRecord.password, context.lng)\n\n const salt = User.generateSalt()\n const result = await userRepo.save({\n ...(newRecord as any),\n domains: [domain],\n salt,\n password: User.encode(newRecord.password, salt),\n passwordUpdatedAt: new Date(),\n creator: user,\n updater: user\n })\n\n // repository api는 작동하지 않음.\n // await tx\n // .createQueryBuilder()\n // .insert()\n // .into('users_domains')\n // .values({\n // usersId: result.id,\n // domainsId: domain.id\n // })\n // .execute()\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(updateRecord.password, context.lng)\n\n const user = await userRepo.findOne({ where: { id: updateRecord.id }, relations: ['domains'] })\n var domains = user.domains.find(d => d.id === domain.id) ? user.domains : [...user.domains, domain]\n\n const result = await userRepo.save({\n ...user,\n ...(updateRecord as any),\n domains,\n password: updateRecord.password ? User.encode(updateRecord.password, user.salt) : user.password,\n updater: user\n })\n\n if (!updateRecord.status) {\n continue\n }\n\n // const domain = await user.domain\n // if (!domain) {\n // continue\n // }\n\n // const domainId = domain.id\n // const domains = await user.domains\n // if (!domains.find(domain => domain.id == domainId)) {\n // await tx\n // .createQueryBuilder()\n // .insert()\n // .into('users_domains')\n // .values({\n // usersId: user.id,\n // domainsId: domain.id\n // })\n // .execute()\n // }\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete a user' })\n async deleteUser(@Arg('email', type => GraphQLEmailAddress) email: string, @Ctx() context: ResolverContext) {\n const { tx } = context.state\n\n await commonDeleteUser({ email }, tx)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete some users' })\n async deleteUsers(@Arg('emails', type => [String]) emails: string[], @Ctx() context: ResolverContext) {\n const { tx } = context.state\n await commonDeleteUsers({ emails }, tx)\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To invite new user' })\n async inviteUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain } = context.state\n const invitee: User = await getRepository(User).findOne({\n where: { email: ILike(email) },\n relations: ['domains']\n })\n\n if (!invitee) {\n throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))\n }\n\n const existingDomains: Domain[] = invitee.domains\n if (existingDomains.find((d: Domain) => d.id === domain.id)) {\n throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }))\n }\n invitee.domains = [...existingDomains, domain]\n await getRepository(User).save(invitee)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete domain user' })\n async deleteDomainUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { tx, domain } = context.state\n\n let user: User = await tx\n .getRepository(User)\n .findOne({ where: { email: ILike(email) }, relations: ['domains', 'roles', 'roles.domain'] })\n if (!user) {\n throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))\n }\n\n const targetDomainIdx: number = user.domains.findIndex((userDomain: Domain) => userDomain.id === domain.id)\n if (targetDomainIdx < 0) {\n throw new Error(context.t('error.x is not a member of y', { x: user.name, y: domain.name }))\n }\n\n // Remove domain relation with user\n user.domains.splice(targetDomainIdx, 1)\n\n // Remove domain's roles that user has\n user.roles = user.roles.filter((role: Role) => role.domain.id !== domain.id)\n\n await tx.getRepository(User).save(user)\n\n return true\n }\n\n @Directive('@privilege(domainOwnerGranted: true, superUserGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To transfer owner of domain' })\n async transferOwner(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain } = context.state\n const user: User = await getRepository(User).findOne({\n where: { email: ILike(email) }\n })\n domain.owner = user.id\n await getRepository(Domain).save(domain)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To activate user' })\n async activateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const targetUser: User = await tx.getRepository(User).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n targetUser.failCount = 0\n targetUser.status = UserStatus.ACTIVATED\n\n await tx.getRepository(User).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To inactivate user' })\n async inactivateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const targetUser: User = await tx.getRepository(User).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n if (targetUser.userType == 'admin' || targetUser.id === domain.owner) {\n throw new Error('Admin deactivation not allowed')\n }\n\n targetUser.status = UserStatus.INACTIVE\n\n await tx.getRepository(User).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To reset password to default' })\n async resetPasswordToDefault(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const { defaultPassword } = config.get('password')\n if (!defaultPassword) {\n throw new Error('No default password found')\n }\n\n const targetUser: User = await tx.getRepository(User).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n targetUser.salt = User.generateSalt()\n targetUser.password = User.encode(defaultPassword, targetUser.salt)\n await tx.getRepository(User).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To update roles for a user' })\n async updateUserRoles(\n @Arg('userId') userId: string,\n @Arg('availableRoles', type => [ObjectRef]) availableRoles: ObjectRef[],\n @Arg('selectedRoles', type => [ObjectRef]) selectedRoles: ObjectRef[],\n @Ctx() context: ResolverContext\n ) {\n const { domain, tx } = context.state\n let user: User = await tx.getRepository(User).findOne({\n where: { id: userId },\n relations: ['domains', 'roles']\n })\n if (!user) {\n throw new Error('Failed to find user')\n }\n\n if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {\n throw new Error(`User is not belongs to current domain`)\n }\n\n const availableRoleIds: string[] = availableRoles.map((r: Role) => r.id)\n user.roles = user.roles.filter((r: Role) => availableRoleIds.indexOf(r.id) < 0)\n user.roles = user.roles.concat(selectedRoles as Role[])\n\n return await tx.getRepository(User).save(user)\n }\n}\n"]}
1
+ {"version":3,"file":"user-mutation.js","sourceRoot":"","sources":["../../../server/service/user/user-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { ILike, In, SelectQueryBuilder, EntityManager } from 'typeorm'\n\nimport { config } from '@things-factory/env'\nimport { Domain, getRepository, ObjectRef } from '@things-factory/shell'\n\nimport { deleteUser as commonDeleteUser, deleteUsers as commonDeleteUsers } from '../../controllers/delete-user'\nimport { buildDomainUsersQueryBuilder } from '../../utils/get-domain-users'\nimport { Role } from '../role/role'\nimport { User, UserStatus } from './user'\nimport { NewUser, UserPatch } from './user-types'\nimport { USERNAME_ALREADY_EXISTS, EMAIL_ALREADY_EXISTS } from '../../constants/error-code'\n\n@Resolver(User)\nexport class UserMutation {\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To create new user' })\n async createUser(@Arg('user') user: NewUser, @Ctx() context: ResolverContext) {\n const { domain, tx } = context.state\n const { defaultPassword } = config.get('password')\n const { username, email } = user\n const userRepository = getRepository(User, tx)\n\n user.username = username.trim()\n user.email = email.trim()\n\n if (await userRepository.findOne({ where: { username: user.username } })) {\n throw new Error(context.t(USERNAME_ALREADY_EXISTS))\n }\n\n if (await userRepository.findOne({ where: { email: ILike(user.email) } })) {\n throw new Error(context.t(EMAIL_ALREADY_EXISTS))\n }\n\n if (!user.password && !defaultPassword) {\n throw new Error('initial password or default password should be supported.')\n }\n\n // TODO username은 다음 패턴을 따라야 한다. pattern=\"^[A-Za-z0-9]*$\"\n if (!/^[A-Za-z0-9]*$/.test(user.username)) {\n throw new Error(context.t('error.invalid x', { x: context.t('field.username') }))\n }\n\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(user.password, context.lng)\n\n const salt = User.generateSalt()\n\n return await userRepository.save({\n creator: context.state.user,\n updater: context.state.user,\n ...user,\n domains: [domain],\n roles:\n user.roles && user.roles.length\n ? await getRepository(Role, tx).findBy({\n id: In(user.roles.map(role => role.id)),\n domain: { id: domain.id }\n })\n : [],\n salt,\n passwordUpdatedAt: new Date(),\n password: user.password ? User.encode(user.password, salt) : User.encode(defaultPassword, salt)\n })\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To modify user information' })\n async updateUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Arg('patch') patch: UserPatch,\n @Ctx() context: ResolverContext\n ) {\n const { domain, user: updater, tx }: { domain: Domain; user: User; tx?: EntityManager } = context.state\n const qb: SelectQueryBuilder<User> = buildDomainUsersQueryBuilder(domain.id, 'USER')\n const user: User = await qb\n .andWhere('LOWER(USER.email) = :email', { email: email?.toLowerCase().trim() || '' })\n .leftJoinAndSelect('USER.roles', 'ROLES')\n .leftJoinAndSelect('ROLES.domain', 'R_DOMAIN')\n .getOne()\n\n if (patch.roles) {\n patch.roles = await getRepository(Role, tx).find({\n where: { id: In(patch.roles.map((r: Partial<Role>) => r.id)) }\n })\n }\n\n if (patch.status && patch.status === 'activated') {\n user.status = UserStatus.ACTIVATED\n }\n\n return await getRepository(User, tx).save({\n ...user,\n ...patch,\n updater\n } as any)\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => [User], { description: 'To modify multiple users information' })\n async updateMultipleUser(@Arg('patches', type => [UserPatch]) patches: UserPatch[], @Ctx() context: ResolverContext) {\n const { domain, user, tx } = context.state\n const userRepo = getRepository(User, tx)\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(newRecord.password, context.lng)\n\n const salt = User.generateSalt()\n const result = await userRepo.save({\n ...(newRecord as any),\n domains: [domain],\n salt,\n password: User.encode(newRecord.password, salt),\n passwordUpdatedAt: new Date(),\n creator: user,\n updater: user\n })\n\n // repository api는 작동하지 않음.\n // await tx\n // .createQueryBuilder()\n // .insert()\n // .into('users_domains')\n // .values({\n // usersId: result.id,\n // domainsId: domain.id\n // })\n // .execute()\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n // consider if validation password rule is required\n /* check if password is following the rule */\n // User.validatePasswordByRule(updateRecord.password, context.lng)\n\n const user = await userRepo.findOne({ where: { id: updateRecord.id }, relations: ['domains'] })\n var domains = user.domains.find(d => d.id === domain.id) ? user.domains : [...user.domains, domain]\n\n const result = await userRepo.save({\n ...user,\n ...(updateRecord as any),\n domains,\n password: updateRecord.password ? User.encode(updateRecord.password, user.salt) : user.password,\n updater: user\n })\n\n if (!updateRecord.status) {\n continue\n }\n\n // const domain = await user.domain\n // if (!domain) {\n // continue\n // }\n\n // const domainId = domain.id\n // const domains = await user.domains\n // if (!domains.find(domain => domain.id == domainId)) {\n // await tx\n // .createQueryBuilder()\n // .insert()\n // .into('users_domains')\n // .values({\n // usersId: user.id,\n // domainsId: domain.id\n // })\n // .execute()\n // }\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete a user' })\n async deleteUser(@Arg('username') username: string, @Ctx() context: ResolverContext) {\n const { tx } = context.state\n\n await commonDeleteUser({ username }, tx)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete some users' })\n async deleteUsers(@Arg('usernames', type => [String]) usernames: string[], @Ctx() context: ResolverContext) {\n const { tx } = context.state\n await commonDeleteUsers({ usernames }, tx)\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To invite new user' })\n async inviteUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n const invitee: User = await getRepository(User, tx).findOne({\n where: { email: ILike(email) },\n relations: ['domains']\n })\n\n if (!invitee) {\n throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))\n }\n\n const existingDomains: Domain[] = invitee.domains\n if (existingDomains.find((d: Domain) => d.id === domain.id)) {\n throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }))\n }\n invitee.domains = [...existingDomains, domain]\n await getRepository(User, tx).save(invitee)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete domain user' })\n async deleteDomainUser(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { tx, domain } = context.state\n\n let user: User = await getRepository(User, tx).findOne({\n where: { email: ILike(email) },\n relations: ['domains', 'roles', 'roles.domain']\n })\n if (!user) {\n throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))\n }\n\n const targetDomainIdx: number = user.domains.findIndex((userDomain: Domain) => userDomain.id === domain.id)\n if (targetDomainIdx < 0) {\n throw new Error(context.t('error.x is not a member of y', { x: user.name, y: domain.name }))\n }\n\n // Remove domain relation with user\n user.domains.splice(targetDomainIdx, 1)\n\n // Remove domain's roles that user has\n user.roles = user.roles.filter((role: Role) => role.domain.id !== domain.id)\n\n await getRepository(User, tx).save(user)\n\n return true\n }\n\n @Directive('@privilege(domainOwnerGranted: true, superUserGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To transfer owner of domain' })\n async transferOwner(\n @Arg('email', type => GraphQLEmailAddress) email: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n const user: User = await getRepository(User, tx).findOne({\n where: { email: ILike(email) },\n relations: ['domains', 'roles']\n })\n\n if (!user) {\n throw new Error('Failed to find user')\n }\n\n if (user.status !== UserStatus.ACTIVATED) {\n throw new Error('Only activated users are eligible to receive admin privileges.')\n }\n\n if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {\n throw new Error(`User is not belongs to current domain`)\n }\n\n if (user.roles.filter((r: Role) => r.domainId == domain.id).length == 0) {\n throw new Error(`Only users with at least one role in this domain are eligible to receive admin privileges.`)\n }\n\n domain.owner = user.id\n await getRepository(Domain, tx).save(domain)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To activate user' })\n async activateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const targetUser: User = await getRepository(User, tx).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n targetUser.failCount = 0\n targetUser.status = UserStatus.ACTIVATED\n\n await getRepository(User, tx).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To inactivate user' })\n async inactivateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const targetUser: User = await getRepository(User, tx).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n if (targetUser.userType == 'admin' || targetUser.id === domain.owner) {\n throw new Error('Admin deactivation not allowed')\n }\n\n targetUser.status = UserStatus.INACTIVE\n\n await getRepository(User, tx).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To reset password to default' })\n async resetPasswordToDefault(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { tx, domain } = context.state\n\n const { defaultPassword } = config.get('password')\n if (!defaultPassword) {\n throw new Error('No default password found')\n }\n\n const targetUser: User = await getRepository(User, tx).findOne({\n where: { id: userId },\n relations: ['domains']\n })\n if (!targetUser) {\n throw new Error('No user found')\n }\n\n if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {\n throw new Error('User is not belong to domain')\n }\n\n targetUser.salt = User.generateSalt()\n targetUser.password = User.encode(defaultPassword, targetUser.salt)\n await getRepository(User, tx).save(targetUser)\n\n return true\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => User, { description: 'To update roles for a user' })\n async updateUserRoles(\n @Arg('userId') userId: string,\n @Arg('availableRoles', type => [ObjectRef]) availableRoles: ObjectRef[],\n @Arg('selectedRoles', type => [ObjectRef]) selectedRoles: ObjectRef[],\n @Ctx() context: ResolverContext\n ) {\n const { domain, tx } = context.state\n let user: User = await getRepository(User, tx).findOne({\n where: { id: userId },\n relations: ['domains', 'roles']\n })\n if (!user) {\n throw new Error('Failed to find user')\n }\n\n if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {\n throw new Error(`User is not belongs to current domain`)\n }\n\n const availableRoleIds: string[] = availableRoles.map((r: Role) => r.id)\n user.roles = user.roles.filter((r: Role) => availableRoleIds.indexOf(r.id) < 0)\n user.roles = user.roles.concat(selectedRoles as Role[])\n\n return await getRepository(User, tx).save(user)\n }\n}\n"]}
@@ -12,6 +12,7 @@ export declare class PasswordRule {
12
12
  looseCharacterLength?: number;
13
13
  }
14
14
  export declare class NewUser {
15
+ username: string;
15
16
  name: string;
16
17
  description?: string;
17
18
  email: string;
@@ -51,6 +51,10 @@ exports.PasswordRule = PasswordRule = tslib_1.__decorate([
51
51
  let NewUser = class NewUser {
52
52
  };
53
53
  exports.NewUser = NewUser;
54
+ tslib_1.__decorate([
55
+ (0, type_graphql_1.Field)(),
56
+ tslib_1.__metadata("design:type", String)
57
+ ], NewUser.prototype, "username", void 0);
54
58
  tslib_1.__decorate([
55
59
  (0, type_graphql_1.Field)(),
56
60
  tslib_1.__metadata("design:type", String)
@@ -1 +1 @@
1
- {"version":3,"file":"user-types.js","sourceRoot":"","sources":["../../../server/service/user/user-types.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObjectType, InputType, Field, ID, Int } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { ObjectRef } from '@things-factory/shell'\nimport { User } from './user'\n\n@ObjectType()\nexport class PasswordRule {\n @Field({ nullable: true })\n lowerCase?: boolean\n\n @Field({ nullable: true })\n upperCase?: boolean\n\n @Field({ nullable: true })\n digit?: boolean\n\n @Field({ nullable: true })\n specialCharacter?: boolean\n\n @Field({ nullable: true })\n allowRepeat?: boolean\n\n @Field({ nullable: true })\n useTightPattern?: boolean\n\n @Field({ nullable: true })\n useLoosePattern?: boolean\n\n @Field({ nullable: true })\n tightCharacterLength?: number\n\n @Field({ nullable: true })\n looseCharacterLength?: number\n}\n\n@InputType()\nexport class NewUser {\n @Field()\n name: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field(type => GraphQLEmailAddress)\n email: string\n\n @Field({ nullable: true })\n password?: string\n\n @Field({ nullable: true })\n userType?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n roles?: ObjectRef[]\n}\n\n@InputType()\nexport class UserPatch {\n @Field(type => ID, { nullable: true })\n id?: string\n\n @Field({ nullable: true })\n name?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n domains?: [ObjectRef]\n\n @Field({ nullable: true })\n description?: string\n\n @Field(type => GraphQLEmailAddress, { nullable: true })\n email?: string\n\n @Field({ nullable: true })\n password?: string\n\n @Field({ nullable: true })\n status?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n roles?: ObjectRef[]\n\n @Field({ nullable: true })\n userType?: string\n\n @Field({ nullable: true })\n cuFlag?: string\n}\n\n@ObjectType()\nexport class UserList {\n @Field(type => [User], { nullable: true })\n items: User[]\n\n @Field(type => Int, { nullable: true })\n total: number\n}\n"]}
1
+ {"version":3,"file":"user-types.js","sourceRoot":"","sources":["../../../server/service/user/user-types.ts"],"names":[],"mappings":"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","sourcesContent":["import { ObjectType, InputType, Field, ID, Int } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { ObjectRef } from '@things-factory/shell'\nimport { User } from './user'\n\n@ObjectType()\nexport class PasswordRule {\n @Field({ nullable: true })\n lowerCase?: boolean\n\n @Field({ nullable: true })\n upperCase?: boolean\n\n @Field({ nullable: true })\n digit?: boolean\n\n @Field({ nullable: true })\n specialCharacter?: boolean\n\n @Field({ nullable: true })\n allowRepeat?: boolean\n\n @Field({ nullable: true })\n useTightPattern?: boolean\n\n @Field({ nullable: true })\n useLoosePattern?: boolean\n\n @Field({ nullable: true })\n tightCharacterLength?: number\n\n @Field({ nullable: true })\n looseCharacterLength?: number\n}\n\n@InputType()\nexport class NewUser {\n @Field()\n username: string\n\n @Field()\n name: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field(type => GraphQLEmailAddress)\n email: string\n\n @Field({ nullable: true })\n password?: string\n\n @Field({ nullable: true })\n userType?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n roles?: ObjectRef[]\n}\n\n@InputType()\nexport class UserPatch {\n @Field(type => ID, { nullable: true })\n id?: string\n\n @Field({ nullable: true })\n name?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n domains?: [ObjectRef]\n\n @Field({ nullable: true })\n description?: string\n\n @Field(type => GraphQLEmailAddress, { nullable: true })\n email?: string\n\n @Field({ nullable: true })\n password?: string\n\n @Field({ nullable: true })\n status?: string\n\n @Field(type => [ObjectRef], { nullable: true })\n roles?: ObjectRef[]\n\n @Field({ nullable: true })\n userType?: string\n\n @Field({ nullable: true })\n cuFlag?: string\n}\n\n@ObjectType()\nexport class UserList {\n @Field(type => [User], { nullable: true })\n items: User[]\n\n @Field(type => Int, { nullable: true })\n total: number\n}\n"]}
@@ -12,6 +12,7 @@ export declare enum UserStatus {
12
12
  }
13
13
  export declare class User {
14
14
  readonly id: string;
15
+ username: string;
15
16
  name: string;
16
17
  description: string;
17
18
  domains?: Domain[];