@things-factory/auth-base 8.0.0 → 9.0.0-beta.3

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 (212) hide show
  1. package/dist-client/index.d.ts +1 -0
  2. package/dist-client/index.js +1 -0
  3. package/dist-client/index.js.map +1 -1
  4. package/dist-client/tsconfig.tsbuildinfo +1 -1
  5. package/dist-client/verify-webauthn.d.ts +13 -0
  6. package/dist-client/verify-webauthn.js +72 -0
  7. package/dist-client/verify-webauthn.js.map +1 -0
  8. package/dist-server/constants/error-code.d.ts +2 -0
  9. package/dist-server/constants/error-code.js +3 -1
  10. package/dist-server/constants/error-code.js.map +1 -1
  11. package/dist-server/controllers/change-pwd.js +2 -2
  12. package/dist-server/controllers/change-pwd.js.map +1 -1
  13. package/dist-server/controllers/delete-user.js +13 -12
  14. package/dist-server/controllers/delete-user.js.map +1 -1
  15. package/dist-server/controllers/invitation.d.ts +2 -1
  16. package/dist-server/controllers/invitation.js +30 -5
  17. package/dist-server/controllers/invitation.js.map +1 -1
  18. package/dist-server/controllers/profile.d.ts +4 -3
  19. package/dist-server/controllers/profile.js +20 -2
  20. package/dist-server/controllers/profile.js.map +1 -1
  21. package/dist-server/controllers/signin.d.ts +4 -1
  22. package/dist-server/controllers/signin.js +17 -1
  23. package/dist-server/controllers/signin.js.map +1 -1
  24. package/dist-server/controllers/signup.js +13 -4
  25. package/dist-server/controllers/signup.js.map +1 -1
  26. package/dist-server/controllers/unlock-user.js +1 -0
  27. package/dist-server/controllers/unlock-user.js.map +1 -1
  28. package/dist-server/controllers/verification.js +1 -0
  29. package/dist-server/controllers/verification.js.map +1 -1
  30. package/dist-server/middlewares/signin-middleware.js +5 -4
  31. package/dist-server/middlewares/signin-middleware.js.map +1 -1
  32. package/dist-server/middlewares/webauthn-middleware.js.map +1 -1
  33. package/dist-server/migrations/1548206416130-SeedUser.js +2 -1
  34. package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
  35. package/dist-server/router/auth-checkin-router.js +8 -2
  36. package/dist-server/router/auth-checkin-router.js.map +1 -1
  37. package/dist-server/router/auth-private-process-router.js +12 -7
  38. package/dist-server/router/auth-private-process-router.js.map +1 -1
  39. package/dist-server/router/auth-public-process-router.js +20 -9
  40. package/dist-server/router/auth-public-process-router.js.map +1 -1
  41. package/dist-server/router/auth-signin-router.js +10 -4
  42. package/dist-server/router/auth-signin-router.js.map +1 -1
  43. package/dist-server/router/webauthn-router.js +51 -1
  44. package/dist-server/router/webauthn-router.js.map +1 -1
  45. package/dist-server/service/invitation/invitation-mutation.d.ts +3 -2
  46. package/dist-server/service/invitation/invitation-mutation.js +20 -8
  47. package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
  48. package/dist-server/service/user/user-mutation.d.ts +10 -9
  49. package/dist-server/service/user/user-mutation.js +112 -54
  50. package/dist-server/service/user/user-mutation.js.map +1 -1
  51. package/dist-server/service/user/user-types.d.ts +1 -0
  52. package/dist-server/service/user/user-types.js +4 -0
  53. package/dist-server/service/user/user-types.js.map +1 -1
  54. package/dist-server/service/user/user.d.ts +1 -0
  55. package/dist-server/service/user/user.js +40 -14
  56. package/dist-server/service/user/user.js.map +1 -1
  57. package/dist-server/templates/account-unlock-email.d.ts +2 -1
  58. package/dist-server/templates/account-unlock-email.js +1 -1
  59. package/dist-server/templates/account-unlock-email.js.map +1 -1
  60. package/dist-server/templates/invitation-email.d.ts +2 -1
  61. package/dist-server/templates/invitation-email.js +1 -1
  62. package/dist-server/templates/invitation-email.js.map +1 -1
  63. package/dist-server/templates/verification-email.d.ts +2 -1
  64. package/dist-server/templates/verification-email.js +1 -1
  65. package/dist-server/templates/verification-email.js.map +1 -1
  66. package/dist-server/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +6 -6
  68. package/translations/en.json +5 -1
  69. package/translations/ja.json +5 -1
  70. package/translations/ko.json +6 -3
  71. package/translations/ms.json +5 -1
  72. package/translations/zh.json +5 -1
  73. package/client/actions/auth.ts +0 -24
  74. package/client/auth.ts +0 -272
  75. package/client/bootstrap.ts +0 -47
  76. package/client/directive/privileged.ts +0 -28
  77. package/client/index.ts +0 -3
  78. package/client/profiled.ts +0 -83
  79. package/client/reducers/auth.ts +0 -31
  80. package/server/constants/error-code.ts +0 -20
  81. package/server/constants/error-message.ts +0 -0
  82. package/server/constants/max-age.ts +0 -1
  83. package/server/controllers/auth.ts +0 -5
  84. package/server/controllers/change-pwd.ts +0 -99
  85. package/server/controllers/checkin.ts +0 -21
  86. package/server/controllers/delete-user.ts +0 -68
  87. package/server/controllers/invitation.ts +0 -132
  88. package/server/controllers/profile.ts +0 -28
  89. package/server/controllers/reset-password.ts +0 -126
  90. package/server/controllers/signin.ts +0 -79
  91. package/server/controllers/signup.ts +0 -60
  92. package/server/controllers/unlock-user.ts +0 -61
  93. package/server/controllers/utils/make-invitation-token.ts +0 -5
  94. package/server/controllers/utils/make-verification-token.ts +0 -4
  95. package/server/controllers/utils/password-rule.ts +0 -120
  96. package/server/controllers/utils/save-invitation-token.ts +0 -10
  97. package/server/controllers/utils/save-verification-token.ts +0 -12
  98. package/server/controllers/verification.ts +0 -83
  99. package/server/errors/auth-error.ts +0 -24
  100. package/server/errors/index.ts +0 -2
  101. package/server/errors/user-domain-not-match-error.ts +0 -29
  102. package/server/index.ts +0 -37
  103. package/server/middlewares/authenticate-401-middleware.ts +0 -114
  104. package/server/middlewares/domain-authenticate-middleware.ts +0 -78
  105. package/server/middlewares/graphql-authenticate-middleware.ts +0 -13
  106. package/server/middlewares/index.ts +0 -67
  107. package/server/middlewares/jwt-authenticate-middleware.ts +0 -84
  108. package/server/middlewares/signin-middleware.ts +0 -55
  109. package/server/middlewares/webauthn-middleware.ts +0 -127
  110. package/server/migrations/1548206416130-SeedUser.ts +0 -59
  111. package/server/migrations/1566805283882-SeedPrivilege.ts +0 -28
  112. package/server/migrations/index.ts +0 -9
  113. package/server/router/auth-checkin-router.ts +0 -107
  114. package/server/router/auth-private-process-router.ts +0 -107
  115. package/server/router/auth-public-process-router.ts +0 -302
  116. package/server/router/auth-signin-router.ts +0 -55
  117. package/server/router/auth-signup-router.ts +0 -95
  118. package/server/router/index.ts +0 -9
  119. package/server/router/oauth2/index.ts +0 -2
  120. package/server/router/oauth2/oauth2-authorize-router.ts +0 -81
  121. package/server/router/oauth2/oauth2-router.ts +0 -165
  122. package/server/router/oauth2/oauth2-server.ts +0 -262
  123. package/server/router/oauth2/passport-oauth2-client-password.ts +0 -87
  124. package/server/router/oauth2/passport-refresh-token.ts +0 -87
  125. package/server/router/path-base-domain-router.ts +0 -8
  126. package/server/router/site-root-router.ts +0 -48
  127. package/server/router/webauthn-router.ts +0 -87
  128. package/server/routes.ts +0 -80
  129. package/server/service/app-binding/app-binding-mutation.ts +0 -22
  130. package/server/service/app-binding/app-binding-query.ts +0 -92
  131. package/server/service/app-binding/app-binding-types.ts +0 -11
  132. package/server/service/app-binding/app-binding.ts +0 -17
  133. package/server/service/app-binding/index.ts +0 -4
  134. package/server/service/appliance/appliance-mutation.ts +0 -113
  135. package/server/service/appliance/appliance-query.ts +0 -76
  136. package/server/service/appliance/appliance-types.ts +0 -56
  137. package/server/service/appliance/appliance.ts +0 -133
  138. package/server/service/appliance/index.ts +0 -6
  139. package/server/service/application/application-mutation.ts +0 -104
  140. package/server/service/application/application-query.ts +0 -98
  141. package/server/service/application/application-types.ts +0 -76
  142. package/server/service/application/application.ts +0 -216
  143. package/server/service/application/index.ts +0 -6
  144. package/server/service/auth-provider/auth-provider-mutation.ts +0 -159
  145. package/server/service/auth-provider/auth-provider-parameter-spec.ts +0 -24
  146. package/server/service/auth-provider/auth-provider-query.ts +0 -88
  147. package/server/service/auth-provider/auth-provider-type.ts +0 -67
  148. package/server/service/auth-provider/auth-provider.ts +0 -155
  149. package/server/service/auth-provider/index.ts +0 -7
  150. package/server/service/domain-generator/domain-generator-mutation.ts +0 -117
  151. package/server/service/domain-generator/domain-generator-types.ts +0 -46
  152. package/server/service/domain-generator/index.ts +0 -3
  153. package/server/service/granted-role/granted-role-mutation.ts +0 -156
  154. package/server/service/granted-role/granted-role-query.ts +0 -60
  155. package/server/service/granted-role/granted-role.ts +0 -27
  156. package/server/service/granted-role/index.ts +0 -6
  157. package/server/service/index.ts +0 -90
  158. package/server/service/invitation/index.ts +0 -6
  159. package/server/service/invitation/invitation-mutation.ts +0 -63
  160. package/server/service/invitation/invitation-query.ts +0 -33
  161. package/server/service/invitation/invitation-types.ts +0 -11
  162. package/server/service/invitation/invitation.ts +0 -63
  163. package/server/service/login-history/index.ts +0 -5
  164. package/server/service/login-history/login-history-query.ts +0 -51
  165. package/server/service/login-history/login-history-type.ts +0 -12
  166. package/server/service/login-history/login-history.ts +0 -45
  167. package/server/service/partner/index.ts +0 -6
  168. package/server/service/partner/partner-mutation.ts +0 -61
  169. package/server/service/partner/partner-query.ts +0 -102
  170. package/server/service/partner/partner-types.ts +0 -11
  171. package/server/service/partner/partner.ts +0 -57
  172. package/server/service/password-history/index.ts +0 -3
  173. package/server/service/password-history/password-history.ts +0 -16
  174. package/server/service/privilege/index.ts +0 -6
  175. package/server/service/privilege/privilege-directive.ts +0 -77
  176. package/server/service/privilege/privilege-mutation.ts +0 -92
  177. package/server/service/privilege/privilege-query.ts +0 -94
  178. package/server/service/privilege/privilege-types.ts +0 -60
  179. package/server/service/privilege/privilege.ts +0 -102
  180. package/server/service/role/index.ts +0 -6
  181. package/server/service/role/role-mutation.ts +0 -109
  182. package/server/service/role/role-query.ts +0 -155
  183. package/server/service/role/role-types.ts +0 -81
  184. package/server/service/role/role.ts +0 -72
  185. package/server/service/user/domain-query.ts +0 -24
  186. package/server/service/user/index.ts +0 -7
  187. package/server/service/user/user-mutation.ts +0 -413
  188. package/server/service/user/user-query.ts +0 -145
  189. package/server/service/user/user-types.ts +0 -97
  190. package/server/service/user/user.ts +0 -354
  191. package/server/service/users-auth-providers/index.ts +0 -5
  192. package/server/service/users-auth-providers/users-auth-providers.ts +0 -71
  193. package/server/service/verification-token/index.ts +0 -3
  194. package/server/service/verification-token/verification-token.ts +0 -60
  195. package/server/service/web-auth-credential/index.ts +0 -3
  196. package/server/service/web-auth-credential/web-auth-credential.ts +0 -67
  197. package/server/templates/account-unlock-email.ts +0 -65
  198. package/server/templates/invitation-email.ts +0 -66
  199. package/server/templates/reset-password-email.ts +0 -65
  200. package/server/templates/verification-email.ts +0 -66
  201. package/server/types.ts +0 -21
  202. package/server/utils/accepts.ts +0 -11
  203. package/server/utils/access-token-cookie.ts +0 -61
  204. package/server/utils/check-permission.ts +0 -52
  205. package/server/utils/check-user-belongs-domain.ts +0 -19
  206. package/server/utils/check-user-has-role.ts +0 -29
  207. package/server/utils/encrypt-state.ts +0 -22
  208. package/server/utils/get-aes-256-key.ts +0 -13
  209. package/server/utils/get-domain-from-hostname.ts +0 -7
  210. package/server/utils/get-domain-users.ts +0 -38
  211. package/server/utils/get-secret.ts +0 -13
  212. package/server/utils/get-user-domains.ts +0 -112
@@ -1,31 +0,0 @@
1
- import { SET_AUTH, SET_PROFILE } from '../actions/auth'
2
-
3
- const INITIAL_STATE = {
4
- authenticated: false,
5
- accessToken: '',
6
- user: null
7
- }
8
-
9
- const auth = (state = INITIAL_STATE, action) => {
10
- switch (action.type) {
11
- case SET_AUTH:
12
- let auth = action.auth
13
-
14
- return {
15
- ...state,
16
- authenticated: auth.authenticated,
17
- accessToken: auth.accessToken
18
- }
19
-
20
- case SET_PROFILE:
21
- return {
22
- ...state,
23
- user: action.user
24
- }
25
-
26
- default:
27
- return state
28
- }
29
- }
30
-
31
- export default auth
@@ -1,20 +0,0 @@
1
- export const USER_NOT_FOUND = 'user not found'
2
- export const PASSWORD_NOT_MATCHED = 'password-not-matched'
3
- export const USER_NOT_ACTIVATED = 'user not activated'
4
- export const USER_LOCKED = 'user-locked'
5
- export const USER_DELETED = 'user-deleted'
6
- export const NO_AVAILABLE_DOMAIN = 'no-available-domain'
7
- export const UNAVAILABLE_DOMAIN = 'unavailable-domain'
8
- export const NO_SELECTED_DOMAIN = 'no-selected-domain'
9
- export const REDIRECT_TO_DEFAULT_DOMAIN = 'redirect-to-default-domain'
10
- export const TOKEN_INVALID = 'token-invalid'
11
- export const AUTH_INVALID = 'auth-invalid'
12
- export const SUBDOMAIN_NOTFOUND = 'subdomain not found'
13
- export const CONFIRM_PASSWORD_NOT_MATCHED = 'confirm password not matched'
14
- export const PASSWORD_PATTERN_NOT_MATCHED = 'password should match the rule'
15
- export const USER_DUPLICATED = 'user duplicated'
16
- export const PASSWORD_USED_PAST = 'password used in the past'
17
- export const VERIFICATION_ERROR = 'user or verification token not found'
18
- export const AUTHN_VERIFICATION_FAILED = 'authn verification failed'
19
- export const USER_CREDENTIAL_NOT_FOUND = 'user credential not found'
20
- export const AUTH_ERROR = 'auth error'
File without changes
@@ -1 +0,0 @@
1
- export const MAX_AGE = 7 * 24 * 3600 * 1000
@@ -1,5 +0,0 @@
1
- export * from './change-pwd'
2
- export * from './signin'
3
- export * from './signup'
4
- export * from './verification'
5
- export * from './invitation'
@@ -1,99 +0,0 @@
1
- import { ILike } from 'typeorm'
2
- import { config } from '@things-factory/env'
3
- import { getRepository } from '@things-factory/shell'
4
-
5
- import {
6
- CONFIRM_PASSWORD_NOT_MATCHED,
7
- PASSWORD_NOT_MATCHED,
8
- PASSWORD_USED_PAST,
9
- USER_NOT_FOUND
10
- } from '../constants/error-code'
11
- import { AuthError } from '../errors/auth-error'
12
- import { PasswordHistory } from '../service/password-history/password-history'
13
- import { User } from '../service/user/user'
14
-
15
- const HISTORY_SIZE = config.get('password', { history: 0 }).history
16
-
17
- export async function changePwd(attrs, currentPass, newPass, confirmPass, context) {
18
- const { domain } = context.state
19
-
20
- // TODO 이 사용자가 이 도메인에 속한 사용자인지 확인해야함.
21
- const repository = getRepository(User)
22
- const user: User = await repository.findOne({ where: { email: ILike(attrs.email) } })
23
-
24
- if (!user) {
25
- throw new AuthError({
26
- errorCode: USER_NOT_FOUND
27
- })
28
- }
29
-
30
- if (newPass !== confirmPass) {
31
- throw new AuthError({
32
- errorCode: CONFIRM_PASSWORD_NOT_MATCHED
33
- })
34
- }
35
-
36
- if (!User.verify(user.password, currentPass, user.salt)) {
37
- throw new AuthError({
38
- errorCode: PASSWORD_NOT_MATCHED,
39
- detail: {
40
- email: user.email,
41
- failCount: user.failCount
42
- }
43
- })
44
- }
45
-
46
- /* check if password is following the rule */
47
- User.validatePasswordByRule(newPass, context?.lng)
48
-
49
- user.password = User.encode(newPass, user.salt)
50
-
51
- if (HISTORY_SIZE > 0) {
52
- var passwordHistory: PasswordHistory = await getRepository(PasswordHistory).findOneBy({ userId: user.id })
53
- var history = []
54
-
55
- if (passwordHistory) {
56
- try {
57
- history = JSON.parse(passwordHistory.history)
58
- if (!(history instanceof Array)) {
59
- console.error('password history maybe currupted - not an array')
60
- history = []
61
- }
62
- } catch (e) {
63
- console.error('password history currupted - not json format')
64
- }
65
-
66
- const found = history.slice(0, HISTORY_SIZE).find(h => {
67
- return User.verify(h.password, newPass, h.salt)
68
- })
69
-
70
- if (found) {
71
- throw new AuthError({
72
- errorCode: PASSWORD_USED_PAST
73
- })
74
- }
75
- }
76
- }
77
-
78
- await repository.save({
79
- ...user,
80
- passwordUpdatedAt: new Date()
81
- })
82
-
83
- if (HISTORY_SIZE > 0) {
84
- history = [
85
- {
86
- password: user.password,
87
- salt: user.salt
88
- },
89
- ...history
90
- ].slice(0, HISTORY_SIZE)
91
-
92
- await getRepository(PasswordHistory).save({
93
- userId: user.id,
94
- history: JSON.stringify(history)
95
- })
96
- }
97
-
98
- return await user.sign({ subdomain: domain.subdomain })
99
- }
@@ -1,21 +0,0 @@
1
- import { Domain, getRepository } from '@things-factory/shell'
2
-
3
- import { User } from '../service/user/user'
4
- import { getUserDomains } from '../utils/get-user-domains'
5
-
6
- export async function checkin({ userId, subdomain }) {
7
- const userRepo = getRepository(User)
8
- const user = await userRepo.findOne({ where: { id: userId } })
9
- const domains: Partial<Domain>[] = await getUserDomains(user)
10
-
11
- if (!domains?.length) {
12
- return false
13
- }
14
-
15
- const domain = domains.find(domain => domain.subdomain == subdomain)
16
- if (!domain) {
17
- return false
18
- }
19
-
20
- return await user.sign({ subdomain })
21
- }
@@ -1,68 +0,0 @@
1
- import { EntityManager, ILike, In } from 'typeorm'
2
- import { User, UserStatus } from '../service/user/user'
3
- import { AuthError } from '../errors/auth-error'
4
- import { USER_NOT_FOUND } from '../constants/error-code'
5
-
6
- export async function deleteUser(attrs, tx?: EntityManager) {
7
- // TODO 이 사용자가 이 도메인에 속한 사용자인지 확인해야함.
8
- // TODO 다른 도메인에도 포함되어있다면, domains-users 관게와 해당 도메인 관련 정보만 삭제해야 함.
9
-
10
- const repository = tx?.getRepository(User)
11
- const user = await repository.findOne({ where: { email: ILike(attrs.email) } })
12
- if (!user) {
13
- throw new AuthError({
14
- errorCode: USER_NOT_FOUND
15
- })
16
- }
17
-
18
- user.status = UserStatus.DELETED
19
- user.domains = []
20
-
21
- await repository.save(user)
22
-
23
- // repository api는 작동하지 않음.
24
- // await txManager
25
- // .createQueryBuilder()
26
- // .delete()
27
- // .from('users_domains')
28
- // .where({
29
- // usersId: user.id
30
- // })
31
- // .execute()
32
- }
33
-
34
- export async function deleteUsers(attrs, tx?: EntityManager) {
35
- // TODO 이 사용자가 이 도메인에 속한 사용자인지 확인해야함.
36
- // TODO 다른 도메인에도 포함되어있다면, domains-users 관게와 해당 도메인 관련 정보만 삭제해야 함.
37
-
38
- const { emails } = attrs
39
-
40
- const repo = tx?.getRepository(User)
41
-
42
- const users = await repo.find({
43
- where: {
44
- email: In(emails)
45
- }
46
- })
47
-
48
- const userIds = []
49
- users.forEach(user => {
50
- user.status = UserStatus.DELETED
51
- user.domains = []
52
-
53
- userIds.push(user.id)
54
- })
55
-
56
- await repo.save(users)
57
-
58
- // repository api는 작동하지 않음.
59
- // await txManager
60
- // .createQueryBuilder()
61
- // .delete()
62
- // .from('users_domains')
63
- // .where({
64
- // usersId: In(userIds)
65
- // })
66
- // .execute()
67
- return true
68
- }
@@ -1,132 +0,0 @@
1
- import { ILike } from 'typeorm'
2
- import { URL } from 'url'
3
-
4
- import { sendEmail } from '@things-factory/email-base'
5
- import { Domain, getRepository } from '@things-factory/shell'
6
-
7
- import { Invitation } from '../service/invitation/invitation'
8
- import { User } from '../service/user/user'
9
- import { getInvitationEmailForm } from '../templates/invitation-email'
10
- import { makeInvitationToken } from './utils/make-invitation-token'
11
- import { saveInvitationToken } from './utils/save-invitation-token'
12
-
13
- export async function invite(attrs, withEmailInvitation?: Boolean) {
14
- const { email, reference, type, context } = attrs
15
-
16
- var user = await getRepository(User).findOne({ where: { email: ILike(email) }, relations: ['domains'] })
17
- var domains = user.domains
18
-
19
- // TODO reference should not be a domain.id (security reason)
20
-
21
- if (user) {
22
- const domain = domains.find(domain => domain.id == reference)
23
-
24
- if (domain) {
25
- const msg = `user already a member of the ${type}.`
26
- throw new Error(msg)
27
- }
28
- }
29
-
30
- if (withEmailInvitation) {
31
- var invitation = await getRepository(Invitation).findOneBy({
32
- email: ILike(email),
33
- reference,
34
- type
35
- })
36
-
37
- if (!invitation) {
38
- invitation = await getRepository(Invitation).save({
39
- email,
40
- reference,
41
- type
42
- })
43
- }
44
-
45
- return await sendInvitationEmail({
46
- invitation,
47
- context
48
- })
49
- }
50
-
51
- if (user) {
52
- user.domains = [...domains, await getRepository(Domain).findOneBy({ id: reference })]
53
- await getRepository(User).save(user)
54
- } else {
55
- // TODO need to signup
56
- }
57
- }
58
-
59
- export async function acceptInvitation(token) {
60
- var invitation = await getRepository(Invitation).findOneBy({
61
- token
62
- })
63
-
64
- if (!invitation) {
65
- throw new Error(`not found invitation.`)
66
- }
67
-
68
- var { email, reference, type } = invitation
69
-
70
- var user = await getRepository(User).findOne({ where: { email: ILike(email) }, relations: ['domains'] })
71
-
72
- if (user) {
73
- var domains = user.domains
74
- const domain = domains.find(domain => domain.id == reference)
75
-
76
- if (domain) {
77
- const msg = `user already a member of the ${type}.`
78
- throw new Error(msg)
79
- }
80
-
81
- user.domains = [...domains, await getRepository(Domain).findOneBy({ id: reference })]
82
- await getRepository(User).save(user)
83
-
84
- await getRepository(Invitation).delete(invitation.id)
85
- } else {
86
- // TODO goto signup
87
- }
88
-
89
- return true
90
- }
91
-
92
- export async function sendInvitationEmail({ invitation, context }) {
93
- try {
94
- var token = makeInvitationToken()
95
- var verifaction = await saveInvitationToken(invitation.id, token)
96
-
97
- if (verifaction) {
98
- var serviceUrl = new URL(`/auth/accept/${token}`, context.header.referer)
99
-
100
- await sendEmail({
101
- receiver: invitation.email,
102
- subject: 'Invitation',
103
- content: getInvitationEmailForm({
104
- email: invitation.email,
105
- acceptUrl: serviceUrl
106
- })
107
- })
108
-
109
- return true
110
- }
111
- } catch (e) {
112
- return false
113
- }
114
- }
115
-
116
- export async function resendInvitationEmail(
117
- { email, reference, type }: { email: string; reference: string; type: string },
118
- context
119
- ) {
120
- var invitation = await getRepository(Invitation).findOneBy({
121
- email: ILike(email),
122
- reference,
123
- type
124
- })
125
-
126
- if (!invitation) return false
127
-
128
- return await sendInvitationEmail({
129
- invitation,
130
- context
131
- })
132
- }
@@ -1,28 +0,0 @@
1
- import { getRepository } from '@things-factory/shell'
2
-
3
- import { USER_NOT_FOUND } from '../constants/error-code'
4
- import { AuthError } from '../errors/auth-error'
5
- import { User } from '../service/user/user'
6
-
7
- export async function updateProfile({ id }, newProfiles) {
8
- const repository = getRepository(User)
9
- const user = await repository.findOneBy({ id })
10
- if (!user) {
11
- throw new AuthError({
12
- errorCode: USER_NOT_FOUND
13
- })
14
- }
15
-
16
- /* only 'name', 'email' and 'locale' attributes can be changed */
17
- var allowed = ['name', 'email', 'locale']
18
- .filter(attr => attr in newProfiles)
19
- .reduce((sum, attr) => {
20
- sum[attr] = newProfiles[attr]
21
- return sum
22
- }, {})
23
-
24
- return await repository.save({
25
- ...user,
26
- ...allowed
27
- })
28
- }
@@ -1,126 +0,0 @@
1
- import { URL } from 'url'
2
-
3
- import { sendEmail } from '@things-factory/email-base'
4
- import { config } from '@things-factory/env'
5
- import { getRepository } from '@things-factory/shell'
6
-
7
- import { PASSWORD_USED_PAST } from '../constants/error-code'
8
- import { AuthError } from '../errors/auth-error'
9
- import { PasswordHistory } from '../service/password-history/password-history'
10
- import { User } from '../service/user/user'
11
- import { VerificationToken, VerificationTokenType } from '../service/verification-token/verification-token'
12
- import { getResetPasswordEmailForm } from '../templates/reset-password-email'
13
- import { makeVerificationToken } from './utils/make-verification-token'
14
- import { saveVerificationToken } from './utils/save-verification-token'
15
-
16
- const HISTORY_SIZE = config.get('password', { history: 0 }).history
17
-
18
- export async function sendPasswordResetEmail({ user, context }) {
19
- try {
20
- var token = makeVerificationToken()
21
- var verifaction = await saveVerificationToken(user.id, token, VerificationTokenType.PASSWORD_RESET)
22
-
23
- if (verifaction) {
24
- var serviceUrl = new URL(`/auth/reset-password?token=${token}`, context.header.referer)
25
- await sendEmail({
26
- receiver: user.email,
27
- subject: 'Reset your password',
28
- content: getResetPasswordEmailForm({
29
- name: user.name,
30
- resetUrl: serviceUrl
31
- })
32
- })
33
-
34
- return true
35
- }
36
- } catch (e) {
37
- return false
38
- }
39
- }
40
-
41
- export async function resetPassword(token, password, context) {
42
- const { t } = context
43
-
44
- const verificationToken = await getRepository(VerificationToken).findOne({
45
- where: {
46
- token,
47
- type: VerificationTokenType.PASSWORD_RESET
48
- }
49
- })
50
-
51
- if (!verificationToken) {
52
- throw new Error(t('text.invalid verification token'))
53
- }
54
-
55
- const { userId } = verificationToken
56
- if (!userId) {
57
- throw new Error(t('text.invalid verification token'))
58
- }
59
-
60
- var user = await getRepository(User).findOneBy({ id: userId })
61
- if (!user) {
62
- throw new Error(t('error.user not found'))
63
- }
64
-
65
- // if (user.status == UserStatus.INACTIVE) {
66
- // throw new Error(t('text.inactive user'))
67
- // }
68
-
69
- /* check if password is following the rule */
70
- User.validatePasswordByRule(password, context?.lng)
71
-
72
- user.password = User.encode(password, user.salt)
73
-
74
- if (HISTORY_SIZE > 0) {
75
- var passwordHistory: PasswordHistory = await getRepository(PasswordHistory).findOneBy({ userId: user.id })
76
- var history = []
77
-
78
- if (passwordHistory) {
79
- try {
80
- history = JSON.parse(passwordHistory.history)
81
- if (!(history instanceof Array)) {
82
- console.error('password history maybe currupted - not an array')
83
- history = []
84
- }
85
- } catch (e) {
86
- console.error('password history currupted - not json format')
87
- }
88
-
89
- const found = history.slice(0, HISTORY_SIZE).find(h => {
90
- return User.verify(h.password, password, h.salt)
91
- })
92
-
93
- if (found) {
94
- throw new AuthError({
95
- errorCode: PASSWORD_USED_PAST
96
- })
97
- }
98
- }
99
- }
100
-
101
- await getRepository(User).save({
102
- ...user,
103
- passwordUpdatedAt: new Date()
104
- })
105
-
106
- await getRepository(VerificationToken).delete({
107
- userId,
108
- token,
109
- type: VerificationTokenType.PASSWORD_RESET
110
- })
111
-
112
- if (HISTORY_SIZE > 0) {
113
- history = [
114
- {
115
- password: user.password,
116
- salt: user.salt
117
- },
118
- ...history
119
- ].slice(0, HISTORY_SIZE)
120
-
121
- await getRepository(PasswordHistory).save({
122
- userId: user.id,
123
- history: JSON.stringify(history)
124
- })
125
- }
126
- }
@@ -1,79 +0,0 @@
1
- import { ILike } from 'typeorm'
2
- import { getRepository } from '@things-factory/shell'
3
-
4
- import { sendUnlockUserEmail } from '../controllers/unlock-user'
5
- import { AuthError } from '../errors/auth-error'
6
- import { User, UserStatus } from '../service/user/user'
7
-
8
- export async function signin(attrs, context?) {
9
- const { domain } = context?.state || {}
10
-
11
- const repository = getRepository(User)
12
- const user = await repository.findOne({ where: { email: ILike(attrs.email) }, relations: ['domains'] })
13
- if (!user)
14
- throw new AuthError({
15
- errorCode: AuthError.ERROR_CODES.USER_NOT_FOUND
16
- })
17
-
18
- if (user.status == UserStatus.DELETED) {
19
- throw new AuthError({
20
- errorCode: AuthError.ERROR_CODES.USER_DELETED
21
- })
22
- }
23
-
24
- if (user.status == UserStatus.LOCKED) {
25
- sendUnlockUserEmail({
26
- user,
27
- context
28
- })
29
- throw new AuthError({
30
- errorCode: AuthError.ERROR_CODES.USER_LOCKED,
31
- detail: {
32
- email: user.email
33
- }
34
- })
35
- }
36
-
37
- if (!User.verify(user.password, attrs.password, user.salt)) {
38
- user.failCount++
39
- if (user.failCount >= 5) user.status = UserStatus.LOCKED
40
- await repository.save(user)
41
- if (user.status == UserStatus.LOCKED) {
42
- sendUnlockUserEmail({
43
- user,
44
- context
45
- })
46
- throw new AuthError({
47
- errorCode: AuthError.ERROR_CODES.USER_LOCKED,
48
- detail: {
49
- email: user.email
50
- }
51
- })
52
- }
53
- throw new AuthError({
54
- errorCode: AuthError.ERROR_CODES.PASSWORD_NOT_MATCHED,
55
- detail: {
56
- email: user.email,
57
- failCount: user.failCount
58
- }
59
- })
60
- } else {
61
- user.failCount = 0
62
- await repository.save(user)
63
- }
64
-
65
- if (user.status == UserStatus.INACTIVE) {
66
- throw new AuthError({
67
- errorCode: AuthError.ERROR_CODES.USER_NOT_ACTIVATED,
68
- detail: {
69
- email: user.email
70
- }
71
- })
72
- }
73
-
74
- return {
75
- user,
76
- token: await user.sign({ subdomain: domain?.subdomain }),
77
- domains: user.domains || []
78
- }
79
- }
@@ -1,60 +0,0 @@
1
- import { ILike } from 'typeorm'
2
- import { getRepository } from '@things-factory/shell'
3
-
4
- import { USER_DUPLICATED } from '../constants/error-code'
5
- import { AuthError } from '../errors/auth-error'
6
- import { User } from '../service/user/user'
7
- import { signin } from './signin'
8
- import { sendVerificationEmail } from './verification'
9
-
10
- export async function signup(attrs, withEmailVerification?: Boolean) {
11
- const { name, email, password, domain, context } = attrs
12
-
13
- /* check if password is following the rule */
14
- User.validatePasswordByRule(password, context.lng)
15
-
16
- const repository = getRepository(User)
17
- const duplicated = await repository.findOneBy({ email: ILike(email) })
18
- if (duplicated) {
19
- throw new AuthError({
20
- errorCode: USER_DUPLICATED,
21
- detail: {
22
- name,
23
- email
24
- }
25
- })
26
- }
27
-
28
- const salt = User.generateSalt()
29
-
30
- var user = await repository.save({
31
- userType: 'user',
32
- ...attrs,
33
- salt,
34
- password: User.encode(password, salt),
35
- passwordUpdatedAt: new Date(),
36
- domains: domain ? [domain] : []
37
- })
38
-
39
- var succeed = false
40
- if (withEmailVerification) {
41
- succeed = await sendVerificationEmail({
42
- context,
43
- user
44
- })
45
- }
46
-
47
- try {
48
- return {
49
- token: await signin(
50
- {
51
- email,
52
- password
53
- },
54
- { domain }
55
- )
56
- }
57
- } catch (e) {
58
- return { token: null }
59
- }
60
- }