@things-factory/auth-base 8.0.0-beta.8 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/client/actions/auth.ts +24 -0
  2. package/client/auth.ts +272 -0
  3. package/client/bootstrap.ts +47 -0
  4. package/client/directive/privileged.ts +28 -0
  5. package/client/index.ts +3 -0
  6. package/client/profiled.ts +83 -0
  7. package/client/reducers/auth.ts +31 -0
  8. package/dist-client/index.d.ts +0 -1
  9. package/dist-client/index.js +0 -1
  10. package/dist-client/index.js.map +1 -1
  11. package/dist-client/tsconfig.tsbuildinfo +1 -1
  12. package/dist-server/constants/error-code.d.ts +0 -2
  13. package/dist-server/constants/error-code.js +1 -3
  14. package/dist-server/constants/error-code.js.map +1 -1
  15. package/dist-server/controllers/change-pwd.js +2 -2
  16. package/dist-server/controllers/change-pwd.js.map +1 -1
  17. package/dist-server/controllers/delete-user.js +12 -13
  18. package/dist-server/controllers/delete-user.js.map +1 -1
  19. package/dist-server/controllers/invitation.d.ts +1 -2
  20. package/dist-server/controllers/invitation.js +5 -30
  21. package/dist-server/controllers/invitation.js.map +1 -1
  22. package/dist-server/controllers/profile.d.ts +3 -4
  23. package/dist-server/controllers/profile.js +2 -20
  24. package/dist-server/controllers/profile.js.map +1 -1
  25. package/dist-server/controllers/signin.d.ts +1 -4
  26. package/dist-server/controllers/signin.js +1 -17
  27. package/dist-server/controllers/signin.js.map +1 -1
  28. package/dist-server/controllers/signup.js +4 -13
  29. package/dist-server/controllers/signup.js.map +1 -1
  30. package/dist-server/controllers/unlock-user.js +0 -1
  31. package/dist-server/controllers/unlock-user.js.map +1 -1
  32. package/dist-server/controllers/verification.js +0 -1
  33. package/dist-server/controllers/verification.js.map +1 -1
  34. package/dist-server/middlewares/signin-middleware.js +4 -9
  35. package/dist-server/middlewares/signin-middleware.js.map +1 -1
  36. package/dist-server/middlewares/webauthn-middleware.js.map +1 -1
  37. package/dist-server/migrations/1548206416130-SeedUser.js +1 -2
  38. package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
  39. package/dist-server/router/auth-checkin-router.js +2 -8
  40. package/dist-server/router/auth-checkin-router.js.map +1 -1
  41. package/dist-server/router/auth-private-process-router.js +7 -12
  42. package/dist-server/router/auth-private-process-router.js.map +1 -1
  43. package/dist-server/router/auth-public-process-router.js +9 -20
  44. package/dist-server/router/auth-public-process-router.js.map +1 -1
  45. package/dist-server/router/auth-signin-router.js +3 -3
  46. package/dist-server/router/auth-signin-router.js.map +1 -1
  47. package/dist-server/router/webauthn-router.js +1 -51
  48. package/dist-server/router/webauthn-router.js.map +1 -1
  49. package/dist-server/service/invitation/invitation-mutation.d.ts +2 -3
  50. package/dist-server/service/invitation/invitation-mutation.js +8 -20
  51. package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
  52. package/dist-server/service/user/user-mutation.d.ts +9 -10
  53. package/dist-server/service/user/user-mutation.js +54 -112
  54. package/dist-server/service/user/user-mutation.js.map +1 -1
  55. package/dist-server/service/user/user-types.d.ts +0 -1
  56. package/dist-server/service/user/user-types.js +0 -4
  57. package/dist-server/service/user/user-types.js.map +1 -1
  58. package/dist-server/service/user/user.d.ts +0 -1
  59. package/dist-server/service/user/user.js +14 -40
  60. package/dist-server/service/user/user.js.map +1 -1
  61. package/dist-server/templates/account-unlock-email.d.ts +1 -2
  62. package/dist-server/templates/account-unlock-email.js +1 -1
  63. package/dist-server/templates/account-unlock-email.js.map +1 -1
  64. package/dist-server/templates/invitation-email.d.ts +1 -2
  65. package/dist-server/templates/invitation-email.js +1 -1
  66. package/dist-server/templates/invitation-email.js.map +1 -1
  67. package/dist-server/templates/verification-email.d.ts +1 -2
  68. package/dist-server/templates/verification-email.js +1 -1
  69. package/dist-server/templates/verification-email.js.map +1 -1
  70. package/dist-server/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +6 -6
  72. package/server/constants/error-code.ts +20 -0
  73. package/server/constants/error-message.ts +0 -0
  74. package/server/constants/max-age.ts +1 -0
  75. package/server/controllers/auth.ts +5 -0
  76. package/server/controllers/change-pwd.ts +99 -0
  77. package/server/controllers/checkin.ts +21 -0
  78. package/server/controllers/delete-user.ts +68 -0
  79. package/server/controllers/invitation.ts +132 -0
  80. package/server/controllers/profile.ts +28 -0
  81. package/server/controllers/reset-password.ts +126 -0
  82. package/server/controllers/signin.ts +79 -0
  83. package/server/controllers/signup.ts +60 -0
  84. package/server/controllers/unlock-user.ts +61 -0
  85. package/server/controllers/utils/make-invitation-token.ts +5 -0
  86. package/server/controllers/utils/make-verification-token.ts +4 -0
  87. package/server/controllers/utils/password-rule.ts +120 -0
  88. package/server/controllers/utils/save-invitation-token.ts +10 -0
  89. package/server/controllers/utils/save-verification-token.ts +12 -0
  90. package/server/controllers/verification.ts +83 -0
  91. package/server/errors/auth-error.ts +24 -0
  92. package/server/errors/index.ts +2 -0
  93. package/server/errors/user-domain-not-match-error.ts +29 -0
  94. package/server/index.ts +37 -0
  95. package/server/middlewares/authenticate-401-middleware.ts +114 -0
  96. package/server/middlewares/domain-authenticate-middleware.ts +78 -0
  97. package/server/middlewares/graphql-authenticate-middleware.ts +13 -0
  98. package/server/middlewares/index.ts +67 -0
  99. package/server/middlewares/jwt-authenticate-middleware.ts +84 -0
  100. package/server/middlewares/signin-middleware.ts +55 -0
  101. package/server/middlewares/webauthn-middleware.ts +127 -0
  102. package/server/migrations/1548206416130-SeedUser.ts +59 -0
  103. package/server/migrations/1566805283882-SeedPrivilege.ts +28 -0
  104. package/server/migrations/index.ts +9 -0
  105. package/server/router/auth-checkin-router.ts +107 -0
  106. package/server/router/auth-private-process-router.ts +107 -0
  107. package/server/router/auth-public-process-router.ts +302 -0
  108. package/server/router/auth-signin-router.ts +55 -0
  109. package/server/router/auth-signup-router.ts +95 -0
  110. package/server/router/index.ts +9 -0
  111. package/server/router/oauth2/index.ts +2 -0
  112. package/server/router/oauth2/oauth2-authorize-router.ts +81 -0
  113. package/server/router/oauth2/oauth2-router.ts +165 -0
  114. package/server/router/oauth2/oauth2-server.ts +262 -0
  115. package/server/router/oauth2/passport-oauth2-client-password.ts +87 -0
  116. package/server/router/oauth2/passport-refresh-token.ts +87 -0
  117. package/server/router/path-base-domain-router.ts +8 -0
  118. package/server/router/site-root-router.ts +48 -0
  119. package/server/router/webauthn-router.ts +87 -0
  120. package/server/routes.ts +80 -0
  121. package/server/service/app-binding/app-binding-mutation.ts +22 -0
  122. package/server/service/app-binding/app-binding-query.ts +92 -0
  123. package/server/service/app-binding/app-binding-types.ts +11 -0
  124. package/server/service/app-binding/app-binding.ts +17 -0
  125. package/server/service/app-binding/index.ts +4 -0
  126. package/server/service/appliance/appliance-mutation.ts +113 -0
  127. package/server/service/appliance/appliance-query.ts +76 -0
  128. package/server/service/appliance/appliance-types.ts +56 -0
  129. package/server/service/appliance/appliance.ts +133 -0
  130. package/server/service/appliance/index.ts +6 -0
  131. package/server/service/application/application-mutation.ts +104 -0
  132. package/server/service/application/application-query.ts +98 -0
  133. package/server/service/application/application-types.ts +76 -0
  134. package/server/service/application/application.ts +216 -0
  135. package/server/service/application/index.ts +6 -0
  136. package/server/service/auth-provider/auth-provider-mutation.ts +159 -0
  137. package/server/service/auth-provider/auth-provider-parameter-spec.ts +24 -0
  138. package/server/service/auth-provider/auth-provider-query.ts +88 -0
  139. package/server/service/auth-provider/auth-provider-type.ts +67 -0
  140. package/server/service/auth-provider/auth-provider.ts +155 -0
  141. package/server/service/auth-provider/index.ts +7 -0
  142. package/server/service/domain-generator/domain-generator-mutation.ts +117 -0
  143. package/server/service/domain-generator/domain-generator-types.ts +46 -0
  144. package/server/service/domain-generator/index.ts +3 -0
  145. package/server/service/granted-role/granted-role-mutation.ts +156 -0
  146. package/server/service/granted-role/granted-role-query.ts +60 -0
  147. package/server/service/granted-role/granted-role.ts +27 -0
  148. package/server/service/granted-role/index.ts +6 -0
  149. package/server/service/index.ts +90 -0
  150. package/server/service/invitation/index.ts +6 -0
  151. package/server/service/invitation/invitation-mutation.ts +63 -0
  152. package/server/service/invitation/invitation-query.ts +33 -0
  153. package/server/service/invitation/invitation-types.ts +11 -0
  154. package/server/service/invitation/invitation.ts +63 -0
  155. package/server/service/login-history/index.ts +5 -0
  156. package/server/service/login-history/login-history-query.ts +51 -0
  157. package/server/service/login-history/login-history-type.ts +12 -0
  158. package/server/service/login-history/login-history.ts +45 -0
  159. package/server/service/partner/index.ts +6 -0
  160. package/server/service/partner/partner-mutation.ts +61 -0
  161. package/server/service/partner/partner-query.ts +102 -0
  162. package/server/service/partner/partner-types.ts +11 -0
  163. package/server/service/partner/partner.ts +57 -0
  164. package/server/service/password-history/index.ts +3 -0
  165. package/server/service/password-history/password-history.ts +16 -0
  166. package/server/service/privilege/index.ts +6 -0
  167. package/server/service/privilege/privilege-directive.ts +77 -0
  168. package/server/service/privilege/privilege-mutation.ts +92 -0
  169. package/server/service/privilege/privilege-query.ts +94 -0
  170. package/server/service/privilege/privilege-types.ts +60 -0
  171. package/server/service/privilege/privilege.ts +102 -0
  172. package/server/service/role/index.ts +6 -0
  173. package/server/service/role/role-mutation.ts +109 -0
  174. package/server/service/role/role-query.ts +155 -0
  175. package/server/service/role/role-types.ts +81 -0
  176. package/server/service/role/role.ts +72 -0
  177. package/server/service/user/domain-query.ts +24 -0
  178. package/server/service/user/index.ts +7 -0
  179. package/server/service/user/user-mutation.ts +413 -0
  180. package/server/service/user/user-query.ts +145 -0
  181. package/server/service/user/user-types.ts +97 -0
  182. package/server/service/user/user.ts +354 -0
  183. package/server/service/users-auth-providers/index.ts +5 -0
  184. package/server/service/users-auth-providers/users-auth-providers.ts +71 -0
  185. package/server/service/verification-token/index.ts +3 -0
  186. package/server/service/verification-token/verification-token.ts +60 -0
  187. package/server/service/web-auth-credential/index.ts +3 -0
  188. package/server/service/web-auth-credential/web-auth-credential.ts +67 -0
  189. package/server/templates/account-unlock-email.ts +65 -0
  190. package/server/templates/invitation-email.ts +66 -0
  191. package/server/templates/reset-password-email.ts +65 -0
  192. package/server/templates/verification-email.ts +66 -0
  193. package/server/types.ts +21 -0
  194. package/server/utils/accepts.ts +11 -0
  195. package/server/utils/access-token-cookie.ts +61 -0
  196. package/server/utils/check-permission.ts +52 -0
  197. package/server/utils/check-user-belongs-domain.ts +19 -0
  198. package/server/utils/check-user-has-role.ts +29 -0
  199. package/server/utils/encrypt-state.ts +22 -0
  200. package/server/utils/get-aes-256-key.ts +13 -0
  201. package/server/utils/get-domain-from-hostname.ts +7 -0
  202. package/server/utils/get-domain-users.ts +38 -0
  203. package/server/utils/get-secret.ts +13 -0
  204. package/server/utils/get-user-domains.ts +112 -0
  205. package/translations/en.json +1 -5
  206. package/translations/ja.json +1 -5
  207. package/translations/ko.json +3 -6
  208. package/translations/ms.json +1 -5
  209. package/translations/zh.json +1 -5
  210. package/dist-client/verify-webauthn.d.ts +0 -13
  211. package/dist-client/verify-webauthn.js +0 -72
  212. package/dist-client/verify-webauthn.js.map +0 -1
@@ -0,0 +1,302 @@
1
+ import Router from 'koa-router'
2
+
3
+ import { config } from '@things-factory/env'
4
+ import { getRepository, getSiteRootPath } from '@things-factory/shell'
5
+
6
+ import { resendInvitationEmail } from '../controllers/invitation'
7
+ import { resetPassword, sendPasswordResetEmail } from '../controllers/reset-password'
8
+ import { unlockUser } from '../controllers/unlock-user'
9
+ import { resendVerificationEmail, verify } from '../controllers/verification'
10
+ import { User } from '../service/user/user'
11
+ import { accepts } from '../utils/accepts'
12
+ import { clearAccessTokenCookie } from '../utils/access-token-cookie'
13
+
14
+ const disableUserSignupProcess = config.get('disableUserSignupProcess', false)
15
+ const disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)
16
+ const languages = config.get('i18n/languages', false)
17
+ const passwordRule = config.get('password') || {
18
+ lowerCase: true,
19
+ upperCase: true,
20
+ digit: true,
21
+ specialCharacter: true,
22
+ allowRepeat: false,
23
+ useTightPattern: true,
24
+ useLoosePattern: false,
25
+ tightCharacterLength: 8,
26
+ looseCharacterLength: 15
27
+ }
28
+
29
+ export const authPublicProcessRouter = new Router({
30
+ prefix: '/auth'
31
+ })
32
+
33
+ authPublicProcessRouter.post('/join', async (context, next) => {
34
+ const { email } = context.request.body || {}
35
+
36
+ const user: User = await getRepository(User).findOneBy({
37
+ email
38
+ })
39
+
40
+ if (user) {
41
+ context.redirect(`/auth/signin?email=${email}`)
42
+ } else {
43
+ context.redirect(`/auth/signup?email=${email}`)
44
+ }
45
+ })
46
+
47
+ authPublicProcessRouter.all('/signout', async (context, next) => {
48
+ const { header, t } = context
49
+ clearAccessTokenCookie(context)
50
+
51
+ context.body = t('text.signout successfully')
52
+
53
+ if (accepts(header.accept, ['text/html', '*/*'])) {
54
+ context.redirect(getSiteRootPath(context))
55
+ }
56
+ })
57
+
58
+ authPublicProcessRouter.get('/forgot-password', async (context, next) => {
59
+ const { email } = context.request.query
60
+
61
+ await context.render('auth-page', {
62
+ pageElement: 'forgot-password',
63
+ elementScript: '/auth/forgot-password.js',
64
+ data: {
65
+ email,
66
+ disableUserSignupProcess,
67
+ disableUserFavoredLanguage,
68
+ languages
69
+ }
70
+ })
71
+ })
72
+
73
+ authPublicProcessRouter.get('/reset-password', async (context, next) => {
74
+ const { token } = context.request.query
75
+
76
+ await context.render('auth-page', {
77
+ pageElement: 'reset-password',
78
+ elementScript: '/auth/reset-password.js',
79
+ data: {
80
+ token,
81
+ passwordRule,
82
+ disableUserSignupProcess,
83
+ disableUserFavoredLanguage,
84
+ languages
85
+ }
86
+ })
87
+ })
88
+
89
+ authPublicProcessRouter.get('/unlock-user', async (context, next) => {
90
+ const { token } = context.request.query
91
+
92
+ await context.render('auth-page', {
93
+ pageElement: 'unlock-user',
94
+ elementScript: '/auth/unlock-user.js',
95
+ data: {
96
+ token,
97
+ disableUserSignupProcess,
98
+ disableUserFavoredLanguage,
99
+ languages
100
+ }
101
+ })
102
+ })
103
+
104
+ authPublicProcessRouter.get('/activate/:email', async (context, next) => {
105
+ const { email } = context.params
106
+
107
+ await context.render('auth-page', {
108
+ pageElement: 'auth-activate',
109
+ elementScript: '/auth/activate.js',
110
+ data: {
111
+ email,
112
+ disableUserSignupProcess,
113
+ disableUserFavoredLanguage,
114
+ languages
115
+ }
116
+ })
117
+ })
118
+
119
+ authPublicProcessRouter.get('/verify/:token', async (context, next) => {
120
+ const { header, t } = context
121
+ var token = context.params.token
122
+
123
+ await verify(token)
124
+
125
+ var message = t('text.user activated successfully')
126
+
127
+ context.body = message
128
+
129
+ if (accepts(header.accept, ['text/html', '*/*'])) {
130
+ await context.render('auth-page', {
131
+ pageElement: 'auth-result',
132
+ elementScript: '/auth/result.js',
133
+ data: {
134
+ message,
135
+ disableUserSignupProcess,
136
+ disableUserFavoredLanguage,
137
+ languages
138
+ }
139
+ })
140
+ }
141
+ })
142
+
143
+ authPublicProcessRouter.post('/resend-verification-email', async (context, next) => {
144
+ const { t } = context
145
+ const { email } = context.request.body
146
+
147
+ var succeed = await resendVerificationEmail(email, context)
148
+ var message = t('text.verification email sent')
149
+
150
+ if (succeed) {
151
+ context.status = 200
152
+ context.body = message
153
+ }
154
+ })
155
+
156
+ authPublicProcessRouter.post('/resend-invitation-email', async (context, next) => {
157
+ const { t } = context
158
+ const { email, reference, type } = context.request.body
159
+
160
+ var succeed = await resendInvitationEmail(
161
+ {
162
+ email,
163
+ reference,
164
+ type
165
+ },
166
+ context
167
+ )
168
+
169
+ var message = t('text.invitation email sent')
170
+
171
+ if (succeed) {
172
+ context.status = 200
173
+ context.body = message
174
+ }
175
+ })
176
+
177
+ authPublicProcessRouter.post('/forgot-password', async (context, next) => {
178
+ const { t } = context
179
+ const { email } = context.request.body
180
+
181
+ if (!email) return next()
182
+
183
+ const userRepo = getRepository(User)
184
+ const user = await userRepo.findOne({
185
+ where: {
186
+ email
187
+ }
188
+ })
189
+
190
+ const succeed = await sendPasswordResetEmail({
191
+ user,
192
+ context
193
+ })
194
+
195
+ if (succeed) {
196
+ context.status = 200
197
+ context.body = t('text.password reset email sent')
198
+ }
199
+ })
200
+
201
+ authPublicProcessRouter.post('/reset-password', async (context, next) => {
202
+ const { header, t } = context
203
+
204
+ try {
205
+ const { password, token } = context.request.body
206
+
207
+ if (!(token && password)) {
208
+ let message = t('error.token or password is invalid')
209
+
210
+ context.status = 404
211
+ context.body = {
212
+ message
213
+ }
214
+
215
+ if (accepts(header.accept, ['text/html', '*/*'])) {
216
+ await context.render('auth-page', {
217
+ pageElement: 'reset-password',
218
+ elementScript: '/auth/reset-password.js',
219
+ data: {
220
+ token,
221
+ message,
222
+ passwordRule,
223
+ disableUserSignupProcess,
224
+ disableUserFavoredLanguage,
225
+ languages
226
+ }
227
+ })
228
+ }
229
+
230
+ return
231
+ }
232
+
233
+ await resetPassword(token, password, context)
234
+
235
+ var message = t('text.password reset succeed')
236
+ context.body = message
237
+
238
+ clearAccessTokenCookie(context)
239
+
240
+ if (accepts(header.accept, ['text/html', '*/*'])) {
241
+ await context.render('auth-page', {
242
+ pageElement: 'auth-result',
243
+ elementScript: '/auth/result.js',
244
+ data: {
245
+ message,
246
+ disableUserSignupProcess,
247
+ disableUserFavoredLanguage,
248
+ languages
249
+ }
250
+ })
251
+ }
252
+ } catch (e) {
253
+ context.status = 404
254
+ context.body = e.message
255
+
256
+ if (accepts(header.accept, ['text/html', '*/*'])) {
257
+ await context.render('auth-page', {
258
+ pageElement: 'auth-result',
259
+ elementScript: '/auth/result.js',
260
+ data: {
261
+ message: e.message,
262
+ disableUserSignupProcess,
263
+ disableUserFavoredLanguage,
264
+ languages
265
+ }
266
+ })
267
+ }
268
+ }
269
+ })
270
+
271
+ authPublicProcessRouter.post('/unlock-user', async (context, next) => {
272
+ const { header, t } = context
273
+ const { password, token } = context.request.body
274
+
275
+ if (!(token || password)) {
276
+ context.status = 404
277
+ context.body = t('error.token or password is invalid')
278
+
279
+ return
280
+ }
281
+
282
+ var succeed = await unlockUser(token, password)
283
+
284
+ if (succeed) {
285
+ context.body = t('text.password reset succeed')
286
+
287
+ clearAccessTokenCookie(context)
288
+ }
289
+
290
+ if (accepts(header.accept, ['text/html', '*/*'])) {
291
+ await context.render('auth-page', {
292
+ pageElement: 'auth-result',
293
+ elementScript: '/auth/result.js',
294
+ data: {
295
+ message: t('text.account is reactivated'),
296
+ disableUserSignupProcess,
297
+ disableUserFavoredLanguage,
298
+ languages
299
+ }
300
+ })
301
+ }
302
+ })
@@ -0,0 +1,55 @@
1
+ import Router from 'koa-router'
2
+
3
+ import { config } from '@things-factory/env'
4
+ import { signinMiddleware } from '../middlewares'
5
+ import { accepts } from '../utils/accepts'
6
+ import { setAccessTokenCookie } from '../utils/access-token-cookie'
7
+
8
+ const disableUserSignupProcess = config.get('disableUserSignupProcess', false)
9
+ const disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)
10
+ const languages = config.get('i18n/languages', false)
11
+
12
+ const SSOConfig = config.get('sso', {} as any)
13
+ const SSOLinks = Object.values(SSOConfig)
14
+ .filter(({ link, title }) => link && title)
15
+ .map(({ link, title }) => {
16
+ return { link, title }
17
+ })
18
+
19
+ export const authSigninRouter = new Router()
20
+
21
+ authSigninRouter.get('/auth/signin', async (context, next) => {
22
+ const { redirect_to, email } = context.query
23
+
24
+ await context.render('auth-page', {
25
+ pageElement: 'auth-signin',
26
+ elementScript: '/auth/signin.js',
27
+ data: {
28
+ email,
29
+ redirectTo: redirect_to,
30
+ ssoLinks: SSOLinks,
31
+ disableUserSignupProcess,
32
+ disableUserFavoredLanguage,
33
+ languages
34
+ }
35
+ })
36
+ })
37
+
38
+ authSigninRouter.post('/auth/signin', signinMiddleware, async (context, next) => {
39
+ const { request, t } = context
40
+ const { token, user, domain } = context.state
41
+ const { body: reqBody, header } = request
42
+
43
+ if (!accepts(header.accept, ['text/html', '*/*'])) {
44
+ context.body = token
45
+ return
46
+ }
47
+
48
+ var redirectTo = `/auth/checkin${domain ? '/' + domain.subdomain : ''}?redirect_to=${encodeURIComponent(
49
+ reqBody.redirectTo || '/'
50
+ )}`
51
+
52
+ setAccessTokenCookie(context, token)
53
+
54
+ context.redirect(redirectTo)
55
+ })
@@ -0,0 +1,95 @@
1
+ import Router from 'koa-router'
2
+
3
+ import { config } from '@things-factory/env'
4
+
5
+ import { signup } from '../controllers/signup'
6
+ import { accepts } from '../utils/accepts'
7
+ import { setAccessTokenCookie } from '../utils/access-token-cookie'
8
+
9
+ const disableUserSignupProcess = config.get('disableUserSignupProcess', false)
10
+ const disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)
11
+ const languages = config.get('i18n/languages', false)
12
+
13
+ const passwordRule = config.get('password') || {
14
+ lowerCase: true,
15
+ upperCase: true,
16
+ digit: true,
17
+ specialCharacter: true,
18
+ allowRepeat: false,
19
+ useTightPattern: true,
20
+ useLoosePattern: false,
21
+ tightCharacterLength: 8,
22
+ looseCharacterLength: 15
23
+ }
24
+
25
+ export const authSignupRouter = new Router()
26
+
27
+ if (!disableUserSignupProcess) {
28
+ authSignupRouter.get('/auth/signup', async (context, next) => {
29
+ const { email } = context.query
30
+
31
+ await context.render('auth-page', {
32
+ pageElement: 'auth-signup',
33
+ elementScript: '/auth/signup.js',
34
+ data: {
35
+ email,
36
+ passwordRule,
37
+ disableUserSignupProcess,
38
+ disableUserFavoredLanguage,
39
+ languages
40
+ }
41
+ })
42
+ })
43
+
44
+ authSignupRouter.post('/auth/signup', async (context, next) => {
45
+ const { header, t } = context
46
+ const { domain } = context.state
47
+ const user = context.request.body
48
+
49
+ // try {
50
+ const { token } = await signup(
51
+ {
52
+ ...user,
53
+ context,
54
+ domain
55
+ },
56
+ true
57
+ )
58
+
59
+ const message = t('text.user registered successfully')
60
+ context.body = {
61
+ message,
62
+ token
63
+ }
64
+
65
+ setAccessTokenCookie(context, token)
66
+
67
+ if (accepts(header.accept, ['text/html', '*/*'])) {
68
+ await context.render('auth-page', {
69
+ pageElement: 'auth-result',
70
+ elementScript: '/auth/result.js',
71
+ data: {
72
+ message,
73
+ disableUserSignupProcess,
74
+ disableUserFavoredLanguage,
75
+ languages
76
+ }
77
+ })
78
+ }
79
+ // } catch (e) {
80
+ // context.status = 401
81
+ // context.body = e.message
82
+
83
+ // if (accepts(header.accept, ['text/html', '*/*'])) {
84
+ // await context.render('auth-page', {
85
+ // pageElement: 'auth-signup',
86
+ // elementScript: '/auth/signup.js',
87
+ // data: {
88
+ // message: e instanceof AuthError ? t(`error.${e.message}`) : e.message,
89
+ // passwordRule
90
+ // }
91
+ // })
92
+ // }
93
+ // }
94
+ })
95
+ }
@@ -0,0 +1,9 @@
1
+ export * from './auth-private-process-router'
2
+ export * from './auth-public-process-router'
3
+ export * from './path-base-domain-router'
4
+ export * from './site-root-router'
5
+ export * from './oauth2'
6
+ export * from './auth-checkin-router'
7
+ export * from './auth-signin-router'
8
+ export * from './auth-signup-router'
9
+ export * from './webauthn-router'
@@ -0,0 +1,2 @@
1
+ export * from './oauth2-authorize-router'
2
+ export * from './oauth2-router'
@@ -0,0 +1,81 @@
1
+ import Router from 'koa-router'
2
+
3
+ import { getRepository } from '@things-factory/shell'
4
+ import { config } from '@things-factory/env'
5
+
6
+ import { Application } from '../../service/application/application'
7
+ import { NonClient, server as oauth2orizeServer } from './oauth2-server'
8
+
9
+ export const oauth2AuthorizeRouter = new Router()
10
+
11
+ const disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)
12
+ const languages = config.get('i18n/languages', false)
13
+
14
+ // user authorization endpoint
15
+ //
16
+ // `authorization` middleware accepts a `validate` callback which is
17
+ // responsible for validating the client making the authorization request. In
18
+ // doing so, is recommended that the `redirectURI` be checked against a
19
+ // registered value, although security requirements may vary accross
20
+ // implementations. Once validated, the `done` callback must be invoked with
21
+ // a `client` instance, as well as the `redirectURI` to which the user will be
22
+ // redirected after an authorization decision is obtained.
23
+ //
24
+ // This middleware simply initializes a new authorization transaction. It is
25
+ // the application's responsibility to authenticate the user and render a dialog
26
+ // to obtain their approval (displaying details about the client requesting
27
+ // authorization). We accomplish that here by routing through `ensureLoggedIn()`
28
+ // first, and rendering the `dialog` view.
29
+
30
+ oauth2AuthorizeRouter.get(
31
+ '/authorize',
32
+ oauth2orizeServer.authorize(async function (clientID, redirectURI) {
33
+ const client = await getRepository(Application).findOneBy({
34
+ appKey: clientID
35
+ })
36
+ // CONFIRM-ME redirectUrl 의 허용 범위는 ?
37
+ // if (!client.redirectUrl != redirectURI) {
38
+ // return false
39
+ // }
40
+
41
+ return [client || NonClient, redirectURI]
42
+ }),
43
+ async function (context, next) {
44
+ const { oauth2, user, domain } = context.state
45
+
46
+ let pageElement: string = 'oauth2-decision'
47
+ let elementScript: string = '/oauth2/oauth2-decision-page.js'
48
+
49
+ if (oauth2.client.id === NonClient.id) {
50
+ pageElement = 'oauth2-decision-error'
51
+ elementScript = '/oauth2/oauth2-decision-error-page.js'
52
+ }
53
+
54
+ try {
55
+ await context.render('oauth2-page', {
56
+ pageElement,
57
+ elementScript,
58
+ data: {
59
+ domain,
60
+ oauth2: {
61
+ ...oauth2,
62
+ user: {
63
+ id: oauth2.user.id,
64
+ name: oauth2.user.name,
65
+ email: oauth2.user.email
66
+ }
67
+ },
68
+ disableUserFavoredLanguage,
69
+ languages
70
+ }
71
+ })
72
+ // await context.render(decisionPage, {
73
+ // domain: domain,
74
+ // ...oauth2, // client, redirectURI, req { type, clientID, redirectURI, scope, state}, user, transactionID, info, locals
75
+ // availableScopes
76
+ // })
77
+ } catch (e) {
78
+ throw e
79
+ }
80
+ }
81
+ )