@things-factory/auth-base 8.0.0-alpha.29 → 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 +21 -12
  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 +2 -2
  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 +21 -10
  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,24 +12,33 @@ 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
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, tx).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, tx).save(Object.assign(Object.assign({ creator: context.state.user, updater: context.state.user }, user), { domains: [domain], roles: user.roles && user.roles.length
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
33
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 }
@@ -115,14 +124,14 @@ let UserMutation = class UserMutation {
115
124
  }
116
125
  return results;
117
126
  }
118
- async deleteUser(email, context) {
127
+ async deleteUser(username, context) {
119
128
  const { tx } = context.state;
120
- await (0, delete_user_1.deleteUser)({ email }, tx);
129
+ await (0, delete_user_1.deleteUser)({ username }, tx);
121
130
  return true;
122
131
  }
123
- async deleteUsers(emails, context) {
132
+ async deleteUsers(usernames, context) {
124
133
  const { tx } = context.state;
125
- await (0, delete_user_1.deleteUsers)({ emails }, tx);
134
+ await (0, delete_user_1.deleteUsers)({ usernames }, tx);
126
135
  return true;
127
136
  }
128
137
  async inviteUser(email, context) {
@@ -298,7 +307,7 @@ tslib_1.__decorate([
298
307
  (0, type_graphql_1.Directive)('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)'),
299
308
  (0, type_graphql_1.Directive)('@transaction'),
300
309
  (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete a user' }),
301
- 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')),
302
311
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
303
312
  tslib_1.__metadata("design:type", Function),
304
313
  tslib_1.__metadata("design:paramtypes", [String, Object]),
@@ -308,7 +317,7 @@ tslib_1.__decorate([
308
317
  (0, type_graphql_1.Directive)('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)'),
309
318
  (0, type_graphql_1.Directive)('@transaction'),
310
319
  (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete some users' }),
311
- 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])),
312
321
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
313
322
  tslib_1.__metadata("design:type", Function),
314
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, 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'\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 { email } = user\n\n user.email = email.trim()\n\n const oldUser: User = await getRepository(User, tx).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, tx).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('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, 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"]}
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[];
@@ -33,14 +33,9 @@ var UserStatus;
33
33
  let User = User_1 = class User {
34
34
  /* signing for jsonwebtoken */
35
35
  async sign(options) {
36
- var { expiresIn = sessionExpirySeconds, subdomain } = options || {};
36
+ var { expiresIn = sessionExpirySeconds } = options || {};
37
37
  var user = {
38
- id: this.id,
39
- userType: this.userType,
40
- status: this.status,
41
- domain: {
42
- subdomain
43
- }
38
+ username: this.username || this.email
44
39
  };
45
40
  return await jsonwebtoken_1.default.sign(user, get_secret_1.SECRET, {
46
41
  expiresIn,
@@ -117,17 +112,37 @@ let User = User_1 = class User {
117
112
  }
118
113
  }
119
114
  static async checkAuth(decoded) {
120
- if ((decoded === null || decoded === void 0 ? void 0 : decoded.id) === undefined) {
115
+ // id 하위호환성을 위해 단기적으로 유지함
116
+ const { id, username } = decoded || {};
117
+ if (!id && !username) {
121
118
  throw new auth_error_1.AuthError({
122
119
  errorCode: auth_error_1.AuthError.ERROR_CODES.USER_NOT_FOUND
123
120
  });
124
121
  }
125
122
  const repository = (0, shell_1.getRepository)(User_1);
126
- var user = await repository.findOne({
127
- where: { id: decoded.id },
128
- relations: ['domains', 'credentials'],
129
- cache: true
130
- });
123
+ if (id) {
124
+ var user = await repository.findOne({
125
+ where: { id },
126
+ relations: ['domains', 'credentials'],
127
+ cache: true
128
+ });
129
+ }
130
+ else {
131
+ var user = await repository.findOne({
132
+ where: { username },
133
+ relations: ['domains', 'credentials'],
134
+ cache: true
135
+ });
136
+ if (!user && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
137
+ user = await repository.findOne({
138
+ where: {
139
+ email: (0, typeorm_1.ILike)(username)
140
+ },
141
+ relations: ['domains', 'credentials'],
142
+ cache: true
143
+ });
144
+ }
145
+ }
131
146
  if (!user)
132
147
  throw new auth_error_1.AuthError({
133
148
  errorCode: auth_error_1.AuthError.ERROR_CODES.USER_NOT_FOUND
@@ -202,6 +217,11 @@ tslib_1.__decorate([
202
217
  (0, type_graphql_1.Field)(type => type_graphql_1.ID),
203
218
  tslib_1.__metadata("design:type", String)
204
219
  ], User.prototype, "id", void 0);
220
+ tslib_1.__decorate([
221
+ (0, typeorm_1.Column)({ nullable: true }),
222
+ (0, type_graphql_1.Field)({ nullable: true }),
223
+ tslib_1.__metadata("design:type", String)
224
+ ], User.prototype, "username", void 0);
205
225
  tslib_1.__decorate([
206
226
  (0, typeorm_1.Column)(),
207
227
  (0, type_graphql_1.Field)({ nullable: true }),
@@ -339,7 +359,13 @@ tslib_1.__decorate([
339
359
  ], User.prototype, "updatedAt", void 0);
340
360
  exports.User = User = User_1 = tslib_1.__decorate([
341
361
  (0, typeorm_1.Entity)(),
342
- (0, typeorm_1.Index)('ix_user_0', (user) => [user.email], { unique: true }),
362
+ (0, typeorm_1.Index)('ix_user_0', (user) => [user.email], {
363
+ unique: true
364
+ }),
365
+ (0, typeorm_1.Index)('ix_user_1', (user) => [user.username], {
366
+ unique: true,
367
+ where: '"username" IS NOT NULL'
368
+ }),
343
369
  (0, type_graphql_1.ObjectType)()
344
370
  ], User);
345
371
  //# sourceMappingURL=user.js.map