@things-factory/auth-base 8.0.0-beta.9 → 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.
- package/client/actions/auth.ts +24 -0
- package/client/auth.ts +272 -0
- package/client/bootstrap.ts +47 -0
- package/client/directive/privileged.ts +28 -0
- package/client/index.ts +3 -0
- package/client/profiled.ts +83 -0
- package/client/reducers/auth.ts +31 -0
- package/dist-client/index.d.ts +0 -1
- package/dist-client/index.js +0 -1
- package/dist-client/index.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/constants/error-code.d.ts +0 -2
- package/dist-server/constants/error-code.js +1 -3
- package/dist-server/constants/error-code.js.map +1 -1
- package/dist-server/controllers/change-pwd.js +2 -2
- package/dist-server/controllers/change-pwd.js.map +1 -1
- package/dist-server/controllers/delete-user.js +12 -13
- package/dist-server/controllers/delete-user.js.map +1 -1
- package/dist-server/controllers/invitation.d.ts +1 -2
- package/dist-server/controllers/invitation.js +5 -30
- package/dist-server/controllers/invitation.js.map +1 -1
- package/dist-server/controllers/profile.d.ts +3 -4
- package/dist-server/controllers/profile.js +2 -20
- package/dist-server/controllers/profile.js.map +1 -1
- package/dist-server/controllers/signin.d.ts +1 -4
- package/dist-server/controllers/signin.js +1 -17
- package/dist-server/controllers/signin.js.map +1 -1
- package/dist-server/controllers/signup.js +4 -13
- package/dist-server/controllers/signup.js.map +1 -1
- package/dist-server/controllers/unlock-user.js +0 -1
- package/dist-server/controllers/unlock-user.js.map +1 -1
- package/dist-server/controllers/verification.js +0 -1
- package/dist-server/controllers/verification.js.map +1 -1
- package/dist-server/middlewares/signin-middleware.js +4 -9
- package/dist-server/middlewares/signin-middleware.js.map +1 -1
- package/dist-server/middlewares/webauthn-middleware.js.map +1 -1
- package/dist-server/migrations/1548206416130-SeedUser.js +1 -2
- package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
- package/dist-server/router/auth-checkin-router.js +2 -8
- package/dist-server/router/auth-checkin-router.js.map +1 -1
- package/dist-server/router/auth-private-process-router.js +7 -12
- package/dist-server/router/auth-private-process-router.js.map +1 -1
- package/dist-server/router/auth-public-process-router.js +9 -20
- package/dist-server/router/auth-public-process-router.js.map +1 -1
- package/dist-server/router/auth-signin-router.js +3 -3
- package/dist-server/router/auth-signin-router.js.map +1 -1
- package/dist-server/router/webauthn-router.js +1 -51
- package/dist-server/router/webauthn-router.js.map +1 -1
- package/dist-server/service/invitation/invitation-mutation.d.ts +2 -3
- package/dist-server/service/invitation/invitation-mutation.js +8 -20
- package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
- package/dist-server/service/user/user-mutation.d.ts +9 -10
- package/dist-server/service/user/user-mutation.js +54 -112
- package/dist-server/service/user/user-mutation.js.map +1 -1
- package/dist-server/service/user/user-types.d.ts +0 -1
- package/dist-server/service/user/user-types.js +0 -4
- package/dist-server/service/user/user-types.js.map +1 -1
- package/dist-server/service/user/user.d.ts +0 -1
- package/dist-server/service/user/user.js +14 -40
- package/dist-server/service/user/user.js.map +1 -1
- package/dist-server/templates/account-unlock-email.d.ts +1 -2
- package/dist-server/templates/account-unlock-email.js +1 -1
- package/dist-server/templates/account-unlock-email.js.map +1 -1
- package/dist-server/templates/invitation-email.d.ts +1 -2
- package/dist-server/templates/invitation-email.js +1 -1
- package/dist-server/templates/invitation-email.js.map +1 -1
- package/dist-server/templates/verification-email.d.ts +1 -2
- package/dist-server/templates/verification-email.js +1 -1
- package/dist-server/templates/verification-email.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/server/constants/error-code.ts +20 -0
- package/server/constants/error-message.ts +0 -0
- package/server/constants/max-age.ts +1 -0
- package/server/controllers/auth.ts +5 -0
- package/server/controllers/change-pwd.ts +99 -0
- package/server/controllers/checkin.ts +21 -0
- package/server/controllers/delete-user.ts +68 -0
- package/server/controllers/invitation.ts +132 -0
- package/server/controllers/profile.ts +28 -0
- package/server/controllers/reset-password.ts +126 -0
- package/server/controllers/signin.ts +79 -0
- package/server/controllers/signup.ts +60 -0
- package/server/controllers/unlock-user.ts +61 -0
- package/server/controllers/utils/make-invitation-token.ts +5 -0
- package/server/controllers/utils/make-verification-token.ts +4 -0
- package/server/controllers/utils/password-rule.ts +120 -0
- package/server/controllers/utils/save-invitation-token.ts +10 -0
- package/server/controllers/utils/save-verification-token.ts +12 -0
- package/server/controllers/verification.ts +83 -0
- package/server/errors/auth-error.ts +24 -0
- package/server/errors/index.ts +2 -0
- package/server/errors/user-domain-not-match-error.ts +29 -0
- package/server/index.ts +37 -0
- package/server/middlewares/authenticate-401-middleware.ts +114 -0
- package/server/middlewares/domain-authenticate-middleware.ts +78 -0
- package/server/middlewares/graphql-authenticate-middleware.ts +13 -0
- package/server/middlewares/index.ts +67 -0
- package/server/middlewares/jwt-authenticate-middleware.ts +84 -0
- package/server/middlewares/signin-middleware.ts +55 -0
- package/server/middlewares/webauthn-middleware.ts +127 -0
- package/server/migrations/1548206416130-SeedUser.ts +59 -0
- package/server/migrations/1566805283882-SeedPrivilege.ts +28 -0
- package/server/migrations/index.ts +9 -0
- package/server/router/auth-checkin-router.ts +107 -0
- package/server/router/auth-private-process-router.ts +107 -0
- package/server/router/auth-public-process-router.ts +302 -0
- package/server/router/auth-signin-router.ts +55 -0
- package/server/router/auth-signup-router.ts +95 -0
- package/server/router/index.ts +9 -0
- package/server/router/oauth2/index.ts +2 -0
- package/server/router/oauth2/oauth2-authorize-router.ts +81 -0
- package/server/router/oauth2/oauth2-router.ts +165 -0
- package/server/router/oauth2/oauth2-server.ts +262 -0
- package/server/router/oauth2/passport-oauth2-client-password.ts +87 -0
- package/server/router/oauth2/passport-refresh-token.ts +87 -0
- package/server/router/path-base-domain-router.ts +8 -0
- package/server/router/site-root-router.ts +48 -0
- package/server/router/webauthn-router.ts +87 -0
- package/server/routes.ts +80 -0
- package/server/service/app-binding/app-binding-mutation.ts +22 -0
- package/server/service/app-binding/app-binding-query.ts +92 -0
- package/server/service/app-binding/app-binding-types.ts +11 -0
- package/server/service/app-binding/app-binding.ts +17 -0
- package/server/service/app-binding/index.ts +4 -0
- package/server/service/appliance/appliance-mutation.ts +113 -0
- package/server/service/appliance/appliance-query.ts +76 -0
- package/server/service/appliance/appliance-types.ts +56 -0
- package/server/service/appliance/appliance.ts +133 -0
- package/server/service/appliance/index.ts +6 -0
- package/server/service/application/application-mutation.ts +104 -0
- package/server/service/application/application-query.ts +98 -0
- package/server/service/application/application-types.ts +76 -0
- package/server/service/application/application.ts +216 -0
- package/server/service/application/index.ts +6 -0
- package/server/service/auth-provider/auth-provider-mutation.ts +159 -0
- package/server/service/auth-provider/auth-provider-parameter-spec.ts +24 -0
- package/server/service/auth-provider/auth-provider-query.ts +88 -0
- package/server/service/auth-provider/auth-provider-type.ts +67 -0
- package/server/service/auth-provider/auth-provider.ts +155 -0
- package/server/service/auth-provider/index.ts +7 -0
- package/server/service/domain-generator/domain-generator-mutation.ts +117 -0
- package/server/service/domain-generator/domain-generator-types.ts +46 -0
- package/server/service/domain-generator/index.ts +3 -0
- package/server/service/granted-role/granted-role-mutation.ts +156 -0
- package/server/service/granted-role/granted-role-query.ts +60 -0
- package/server/service/granted-role/granted-role.ts +27 -0
- package/server/service/granted-role/index.ts +6 -0
- package/server/service/index.ts +90 -0
- package/server/service/invitation/index.ts +6 -0
- package/server/service/invitation/invitation-mutation.ts +63 -0
- package/server/service/invitation/invitation-query.ts +33 -0
- package/server/service/invitation/invitation-types.ts +11 -0
- package/server/service/invitation/invitation.ts +63 -0
- package/server/service/login-history/index.ts +5 -0
- package/server/service/login-history/login-history-query.ts +51 -0
- package/server/service/login-history/login-history-type.ts +12 -0
- package/server/service/login-history/login-history.ts +45 -0
- package/server/service/partner/index.ts +6 -0
- package/server/service/partner/partner-mutation.ts +61 -0
- package/server/service/partner/partner-query.ts +102 -0
- package/server/service/partner/partner-types.ts +11 -0
- package/server/service/partner/partner.ts +57 -0
- package/server/service/password-history/index.ts +3 -0
- package/server/service/password-history/password-history.ts +16 -0
- package/server/service/privilege/index.ts +6 -0
- package/server/service/privilege/privilege-directive.ts +77 -0
- package/server/service/privilege/privilege-mutation.ts +92 -0
- package/server/service/privilege/privilege-query.ts +94 -0
- package/server/service/privilege/privilege-types.ts +60 -0
- package/server/service/privilege/privilege.ts +102 -0
- package/server/service/role/index.ts +6 -0
- package/server/service/role/role-mutation.ts +109 -0
- package/server/service/role/role-query.ts +155 -0
- package/server/service/role/role-types.ts +81 -0
- package/server/service/role/role.ts +72 -0
- package/server/service/user/domain-query.ts +24 -0
- package/server/service/user/index.ts +7 -0
- package/server/service/user/user-mutation.ts +413 -0
- package/server/service/user/user-query.ts +145 -0
- package/server/service/user/user-types.ts +97 -0
- package/server/service/user/user.ts +354 -0
- package/server/service/users-auth-providers/index.ts +5 -0
- package/server/service/users-auth-providers/users-auth-providers.ts +71 -0
- package/server/service/verification-token/index.ts +3 -0
- package/server/service/verification-token/verification-token.ts +60 -0
- package/server/service/web-auth-credential/index.ts +3 -0
- package/server/service/web-auth-credential/web-auth-credential.ts +67 -0
- package/server/templates/account-unlock-email.ts +65 -0
- package/server/templates/invitation-email.ts +66 -0
- package/server/templates/reset-password-email.ts +65 -0
- package/server/templates/verification-email.ts +66 -0
- package/server/types.ts +21 -0
- package/server/utils/accepts.ts +11 -0
- package/server/utils/access-token-cookie.ts +61 -0
- package/server/utils/check-permission.ts +52 -0
- package/server/utils/check-user-belongs-domain.ts +19 -0
- package/server/utils/check-user-has-role.ts +29 -0
- package/server/utils/encrypt-state.ts +22 -0
- package/server/utils/get-aes-256-key.ts +13 -0
- package/server/utils/get-domain-from-hostname.ts +7 -0
- package/server/utils/get-domain-users.ts +38 -0
- package/server/utils/get-secret.ts +13 -0
- package/server/utils/get-user-domains.ts +112 -0
- package/translations/en.json +1 -5
- package/translations/ja.json +1 -5
- package/translations/ko.json +3 -6
- package/translations/ms.json +1 -5
- package/translations/zh.json +1 -5
- package/dist-client/verify-webauthn.d.ts +0 -13
- package/dist-client/verify-webauthn.js +0 -72
- 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,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
|
+
)
|