@things-factory/auth-base 8.0.0-beta.0 → 8.0.0-beta.2
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/package.json +6 -6
- package/client/actions/auth.ts +0 -24
- package/client/auth.ts +0 -272
- package/client/bootstrap.ts +0 -47
- package/client/directive/privileged.ts +0 -28
- package/client/index.ts +0 -4
- package/client/profiled.ts +0 -83
- package/client/reducers/auth.ts +0 -31
- package/client/verify-webauthn.ts +0 -86
- package/server/constants/error-code.ts +0 -22
- package/server/constants/error-message.ts +0 -0
- package/server/constants/max-age.ts +0 -1
- package/server/controllers/auth.ts +0 -5
- package/server/controllers/change-pwd.ts +0 -100
- package/server/controllers/checkin.ts +0 -21
- package/server/controllers/delete-user.ts +0 -71
- package/server/controllers/invitation.ts +0 -163
- package/server/controllers/profile.ts +0 -55
- package/server/controllers/reset-password.ts +0 -126
- package/server/controllers/signin.ts +0 -98
- package/server/controllers/signup.ts +0 -72
- package/server/controllers/unlock-user.ts +0 -62
- package/server/controllers/utils/make-invitation-token.ts +0 -5
- package/server/controllers/utils/make-verification-token.ts +0 -4
- package/server/controllers/utils/password-rule.ts +0 -120
- package/server/controllers/utils/save-invitation-token.ts +0 -10
- package/server/controllers/utils/save-verification-token.ts +0 -12
- package/server/controllers/verification.ts +0 -84
- package/server/errors/auth-error.ts +0 -24
- package/server/errors/index.ts +0 -2
- package/server/errors/user-domain-not-match-error.ts +0 -29
- package/server/index.ts +0 -37
- package/server/middlewares/authenticate-401-middleware.ts +0 -114
- package/server/middlewares/domain-authenticate-middleware.ts +0 -78
- package/server/middlewares/graphql-authenticate-middleware.ts +0 -13
- package/server/middlewares/index.ts +0 -67
- package/server/middlewares/jwt-authenticate-middleware.ts +0 -84
- package/server/middlewares/signin-middleware.ts +0 -55
- package/server/middlewares/webauthn-middleware.ts +0 -126
- package/server/migrations/1548206416130-SeedUser.ts +0 -60
- package/server/migrations/1566805283882-SeedPrivilege.ts +0 -28
- package/server/migrations/index.ts +0 -9
- package/server/router/auth-checkin-router.ts +0 -113
- package/server/router/auth-private-process-router.ts +0 -114
- package/server/router/auth-public-process-router.ts +0 -314
- package/server/router/auth-signin-router.ts +0 -55
- package/server/router/auth-signup-router.ts +0 -95
- package/server/router/index.ts +0 -9
- package/server/router/oauth2/index.ts +0 -2
- package/server/router/oauth2/oauth2-authorize-router.ts +0 -81
- package/server/router/oauth2/oauth2-router.ts +0 -165
- package/server/router/oauth2/oauth2-server.ts +0 -262
- package/server/router/oauth2/passport-oauth2-client-password.ts +0 -87
- package/server/router/oauth2/passport-refresh-token.ts +0 -87
- package/server/router/path-base-domain-router.ts +0 -8
- package/server/router/site-root-router.ts +0 -48
- package/server/router/webauthn-router.ts +0 -149
- package/server/routes.ts +0 -80
- package/server/service/app-binding/app-binding-mutation.ts +0 -22
- package/server/service/app-binding/app-binding-query.ts +0 -92
- package/server/service/app-binding/app-binding-types.ts +0 -11
- package/server/service/app-binding/app-binding.ts +0 -17
- package/server/service/app-binding/index.ts +0 -4
- package/server/service/appliance/appliance-mutation.ts +0 -113
- package/server/service/appliance/appliance-query.ts +0 -76
- package/server/service/appliance/appliance-types.ts +0 -56
- package/server/service/appliance/appliance.ts +0 -133
- package/server/service/appliance/index.ts +0 -6
- package/server/service/application/application-mutation.ts +0 -104
- package/server/service/application/application-query.ts +0 -98
- package/server/service/application/application-types.ts +0 -76
- package/server/service/application/application.ts +0 -216
- package/server/service/application/index.ts +0 -6
- package/server/service/auth-provider/auth-provider-mutation.ts +0 -159
- package/server/service/auth-provider/auth-provider-parameter-spec.ts +0 -24
- package/server/service/auth-provider/auth-provider-query.ts +0 -88
- package/server/service/auth-provider/auth-provider-type.ts +0 -67
- package/server/service/auth-provider/auth-provider.ts +0 -155
- package/server/service/auth-provider/index.ts +0 -7
- package/server/service/domain-generator/domain-generator-mutation.ts +0 -117
- package/server/service/domain-generator/domain-generator-types.ts +0 -46
- package/server/service/domain-generator/index.ts +0 -3
- package/server/service/granted-role/granted-role-mutation.ts +0 -156
- package/server/service/granted-role/granted-role-query.ts +0 -60
- package/server/service/granted-role/granted-role.ts +0 -27
- package/server/service/granted-role/index.ts +0 -6
- package/server/service/index.ts +0 -90
- package/server/service/invitation/index.ts +0 -6
- package/server/service/invitation/invitation-mutation.ts +0 -78
- package/server/service/invitation/invitation-query.ts +0 -33
- package/server/service/invitation/invitation-types.ts +0 -11
- package/server/service/invitation/invitation.ts +0 -63
- package/server/service/login-history/index.ts +0 -5
- package/server/service/login-history/login-history-query.ts +0 -51
- package/server/service/login-history/login-history-type.ts +0 -12
- package/server/service/login-history/login-history.ts +0 -45
- package/server/service/partner/index.ts +0 -6
- package/server/service/partner/partner-mutation.ts +0 -61
- package/server/service/partner/partner-query.ts +0 -102
- package/server/service/partner/partner-types.ts +0 -11
- package/server/service/partner/partner.ts +0 -57
- package/server/service/password-history/index.ts +0 -3
- package/server/service/password-history/password-history.ts +0 -16
- package/server/service/privilege/index.ts +0 -6
- package/server/service/privilege/privilege-directive.ts +0 -77
- package/server/service/privilege/privilege-mutation.ts +0 -92
- package/server/service/privilege/privilege-query.ts +0 -94
- package/server/service/privilege/privilege-types.ts +0 -60
- package/server/service/privilege/privilege.ts +0 -102
- package/server/service/role/index.ts +0 -6
- package/server/service/role/role-mutation.ts +0 -109
- package/server/service/role/role-query.ts +0 -155
- package/server/service/role/role-types.ts +0 -81
- package/server/service/role/role.ts +0 -72
- package/server/service/user/domain-query.ts +0 -24
- package/server/service/user/index.ts +0 -7
- package/server/service/user/user-mutation.ts +0 -482
- package/server/service/user/user-query.ts +0 -145
- package/server/service/user/user-types.ts +0 -100
- package/server/service/user/user.ts +0 -381
- package/server/service/users-auth-providers/index.ts +0 -5
- package/server/service/users-auth-providers/users-auth-providers.ts +0 -71
- package/server/service/verification-token/index.ts +0 -3
- package/server/service/verification-token/verification-token.ts +0 -60
- package/server/service/web-auth-credential/index.ts +0 -3
- package/server/service/web-auth-credential/web-auth-credential.ts +0 -67
- package/server/templates/account-unlock-email.ts +0 -65
- package/server/templates/invitation-email.ts +0 -66
- package/server/templates/reset-password-email.ts +0 -65
- package/server/templates/verification-email.ts +0 -66
- package/server/types.ts +0 -21
- package/server/utils/accepts.ts +0 -11
- package/server/utils/access-token-cookie.ts +0 -61
- package/server/utils/check-permission.ts +0 -52
- package/server/utils/check-user-belongs-domain.ts +0 -19
- package/server/utils/check-user-has-role.ts +0 -29
- package/server/utils/encrypt-state.ts +0 -22
- package/server/utils/get-aes-256-key.ts +0 -13
- package/server/utils/get-domain-from-hostname.ts +0 -7
- package/server/utils/get-domain-users.ts +0 -38
- package/server/utils/get-secret.ts +0 -13
- package/server/utils/get-user-domains.ts +0 -112
@@ -1,84 +0,0 @@
|
|
1
|
-
import passport from 'koa-passport'
|
2
|
-
import { ExtractJwt, Strategy as JWTstrategy } from 'passport-jwt'
|
3
|
-
|
4
|
-
import { config } from '@things-factory/env'
|
5
|
-
|
6
|
-
import { makeVerificationToken } from '../controllers/utils/make-verification-token'
|
7
|
-
import { saveVerificationToken } from '../controllers/utils/save-verification-token'
|
8
|
-
import { User, UserStatus } from '../service/user/user'
|
9
|
-
import { VerificationTokenType } from '../service/verification-token/verification-token'
|
10
|
-
import { clearAccessTokenCookie, getAccessTokenCookie, setAccessTokenCookie } from '../utils/access-token-cookie'
|
11
|
-
import { SECRET } from '../utils/get-secret'
|
12
|
-
|
13
|
-
const sessionExpiryPolicy = config.get('session/expiryPolicy', 'fixed')
|
14
|
-
|
15
|
-
passport.use(
|
16
|
-
new JWTstrategy(
|
17
|
-
{
|
18
|
-
secretOrKey: SECRET,
|
19
|
-
passReqToCallback: true,
|
20
|
-
jwtFromRequest: ExtractJwt.fromExtractors([
|
21
|
-
ExtractJwt.fromAuthHeaderAsBearerToken(),
|
22
|
-
ExtractJwt.fromHeader('authorization'),
|
23
|
-
ExtractJwt.fromHeader('x-access-token'),
|
24
|
-
ExtractJwt.fromUrlQueryParameter('access_token'),
|
25
|
-
ExtractJwt.fromBodyField('access_token'),
|
26
|
-
req => {
|
27
|
-
var token = null
|
28
|
-
token = getAccessTokenCookie(req?.ctx)
|
29
|
-
return token
|
30
|
-
}
|
31
|
-
])
|
32
|
-
},
|
33
|
-
async (request, decoded, done) => {
|
34
|
-
try {
|
35
|
-
return done(null, decoded)
|
36
|
-
} catch (error) {
|
37
|
-
return done(error)
|
38
|
-
}
|
39
|
-
}
|
40
|
-
)
|
41
|
-
)
|
42
|
-
|
43
|
-
export async function jwtAuthenticateMiddleware(context, next) {
|
44
|
-
const { path } = context
|
45
|
-
const { user } = context.state
|
46
|
-
if (user) {
|
47
|
-
return await next()
|
48
|
-
}
|
49
|
-
|
50
|
-
return await passport.authenticate('jwt', { session: false }, async (err, decoded, info) => {
|
51
|
-
if (err || !decoded) {
|
52
|
-
const e = (context.state.error = err || info)
|
53
|
-
|
54
|
-
clearAccessTokenCookie(context)
|
55
|
-
|
56
|
-
context.throw(401, e.message)
|
57
|
-
} else {
|
58
|
-
const userEntity = await User.checkAuth(decoded)
|
59
|
-
|
60
|
-
if (userEntity.status === UserStatus.PWD_RESET_REQUIRED) {
|
61
|
-
try {
|
62
|
-
const token = makeVerificationToken()
|
63
|
-
await saveVerificationToken(userEntity.id, token, VerificationTokenType.PASSWORD_RESET)
|
64
|
-
clearAccessTokenCookie(context)
|
65
|
-
context.redirect(`/auth/reset-password?token=${token}`)
|
66
|
-
} catch (e) {
|
67
|
-
throw err
|
68
|
-
}
|
69
|
-
} else {
|
70
|
-
context.state.user = userEntity
|
71
|
-
context.state.decodedToken = decoded
|
72
|
-
|
73
|
-
if (sessionExpiryPolicy == 'rolling') {
|
74
|
-
/* To renew the expiry time on each request, a token is issued and the session is updated. */
|
75
|
-
|
76
|
-
const token = await userEntity.sign()
|
77
|
-
setAccessTokenCookie(context, token)
|
78
|
-
}
|
79
|
-
|
80
|
-
await next()
|
81
|
-
}
|
82
|
-
}
|
83
|
-
})(context, next)
|
84
|
-
}
|
@@ -1,55 +0,0 @@
|
|
1
|
-
import passport from 'koa-passport'
|
2
|
-
import { Strategy as localStrategy } from 'passport-local'
|
3
|
-
|
4
|
-
import { signin } from '../controllers/signin'
|
5
|
-
|
6
|
-
passport.use(
|
7
|
-
'signin',
|
8
|
-
new localStrategy(
|
9
|
-
{
|
10
|
-
usernameField: 'username',
|
11
|
-
passwordField: 'password'
|
12
|
-
},
|
13
|
-
async (username, password, done) => {
|
14
|
-
try {
|
15
|
-
const {
|
16
|
-
user: userInfo,
|
17
|
-
token,
|
18
|
-
domains
|
19
|
-
} = await signin({
|
20
|
-
username,
|
21
|
-
password
|
22
|
-
})
|
23
|
-
|
24
|
-
return done(
|
25
|
-
null,
|
26
|
-
{
|
27
|
-
user: userInfo,
|
28
|
-
token,
|
29
|
-
domains
|
30
|
-
},
|
31
|
-
{
|
32
|
-
message: 'Logged in Successfully'
|
33
|
-
}
|
34
|
-
)
|
35
|
-
} catch (error) {
|
36
|
-
return done(error)
|
37
|
-
}
|
38
|
-
}
|
39
|
-
)
|
40
|
-
)
|
41
|
-
|
42
|
-
export async function signinMiddleware(context, next) {
|
43
|
-
return passport.authenticate('signin', { session: false }, async (err, user, info) => {
|
44
|
-
if (err || !user) {
|
45
|
-
throw err
|
46
|
-
} else {
|
47
|
-
const { user: userInfo, token } = user
|
48
|
-
|
49
|
-
context.state.user = userInfo
|
50
|
-
context.state.token = token
|
51
|
-
|
52
|
-
await next()
|
53
|
-
}
|
54
|
-
})(context, next)
|
55
|
-
}
|
@@ -1,126 +0,0 @@
|
|
1
|
-
import passport from 'koa-passport'
|
2
|
-
import { Strategy as CustomStrategy } from 'passport-custom'
|
3
|
-
|
4
|
-
import { getRepository } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { AuthError } from '../errors/auth-error'
|
7
|
-
|
8
|
-
import { WebAuthCredential } from '../service/web-auth-credential/web-auth-credential'
|
9
|
-
import { verifyRegistrationResponse, verifyAuthenticationResponse } from '@simplewebauthn/server'
|
10
|
-
|
11
|
-
import { AuthenticatorAssertionResponse } from '@simplewebauthn/types'
|
12
|
-
|
13
|
-
passport.use(
|
14
|
-
'webauthn-register',
|
15
|
-
new CustomStrategy(async (context, done) => {
|
16
|
-
const { body, session, user, hostname, origin } = context as any
|
17
|
-
|
18
|
-
const challenge = session.challenge
|
19
|
-
|
20
|
-
const verification = await verifyRegistrationResponse({
|
21
|
-
response: body,
|
22
|
-
expectedChallenge: challenge,
|
23
|
-
expectedOrigin: origin,
|
24
|
-
expectedRPID: hostname,
|
25
|
-
expectedType: 'webauthn.create',
|
26
|
-
requireUserVerification: false
|
27
|
-
})
|
28
|
-
|
29
|
-
if (verification.verified) {
|
30
|
-
const { registrationInfo } = verification
|
31
|
-
const publicKey = Buffer.from(registrationInfo.credentialPublicKey).toString('base64')
|
32
|
-
|
33
|
-
if (user) {
|
34
|
-
const webAuthRepository = getRepository(WebAuthCredential)
|
35
|
-
await webAuthRepository.save({
|
36
|
-
user,
|
37
|
-
credentialId: registrationInfo.credentialID,
|
38
|
-
publicKey,
|
39
|
-
counter: registrationInfo.counter,
|
40
|
-
creator: user,
|
41
|
-
updater: user
|
42
|
-
})
|
43
|
-
}
|
44
|
-
|
45
|
-
return done(null, user)
|
46
|
-
} else {
|
47
|
-
return done(null, false)
|
48
|
-
}
|
49
|
-
})
|
50
|
-
)
|
51
|
-
|
52
|
-
passport.use(
|
53
|
-
'webauthn-login',
|
54
|
-
new CustomStrategy(async (context, done) => {
|
55
|
-
try {
|
56
|
-
const { body, session, origin, hostname } = context as any
|
57
|
-
|
58
|
-
const challenge = session.challenge
|
59
|
-
|
60
|
-
const assertionResponse = body as {
|
61
|
-
id: string
|
62
|
-
response: AuthenticatorAssertionResponse
|
63
|
-
}
|
64
|
-
|
65
|
-
const credential = await getRepository(WebAuthCredential).findOne({
|
66
|
-
where: {
|
67
|
-
credentialId: assertionResponse.id
|
68
|
-
},
|
69
|
-
relations: ['user']
|
70
|
-
})
|
71
|
-
|
72
|
-
if (!credential) {
|
73
|
-
return done(null, false)
|
74
|
-
}
|
75
|
-
|
76
|
-
const verification = await verifyAuthenticationResponse({
|
77
|
-
response: body,
|
78
|
-
expectedChallenge: challenge,
|
79
|
-
expectedOrigin: origin,
|
80
|
-
expectedRPID: hostname,
|
81
|
-
requireUserVerification: false,
|
82
|
-
authenticator: {
|
83
|
-
credentialID: credential.credentialId,
|
84
|
-
credentialPublicKey: new Uint8Array(Buffer.from(credential.publicKey, 'base64')),
|
85
|
-
counter: credential.counter
|
86
|
-
}
|
87
|
-
})
|
88
|
-
|
89
|
-
if (verification.verified) {
|
90
|
-
const { authenticationInfo } = verification
|
91
|
-
credential.counter = authenticationInfo.newCounter
|
92
|
-
await getRepository(WebAuthCredential).save(credential)
|
93
|
-
|
94
|
-
const user = credential.user
|
95
|
-
return done(null, user)
|
96
|
-
} else {
|
97
|
-
return done(verification, false)
|
98
|
-
}
|
99
|
-
} catch (error) {
|
100
|
-
return done(error, false)
|
101
|
-
}
|
102
|
-
})
|
103
|
-
)
|
104
|
-
|
105
|
-
export function createWebAuthnMiddleware(strategy: 'webauthn-register' | 'webauthn-login') {
|
106
|
-
return async function webAuthnMiddleware(context, next) {
|
107
|
-
return passport.authenticate(
|
108
|
-
strategy,
|
109
|
-
{ session: true, failureMessage: true, failWithError: true },
|
110
|
-
async (err, user) => {
|
111
|
-
if (err || !user) {
|
112
|
-
throw new AuthError({
|
113
|
-
errorCode: AuthError.ERROR_CODES.AUTHN_VERIFICATION_FAILED,
|
114
|
-
detail: err
|
115
|
-
})
|
116
|
-
} else {
|
117
|
-
context.state.user = user
|
118
|
-
|
119
|
-
context.body = { user, verified: true }
|
120
|
-
}
|
121
|
-
|
122
|
-
await next()
|
123
|
-
}
|
124
|
-
)(context, next)
|
125
|
-
}
|
126
|
-
}
|
@@ -1,60 +0,0 @@
|
|
1
|
-
import { ILike, MigrationInterface, QueryRunner } from 'typeorm'
|
2
|
-
|
3
|
-
import { config, logger } from '@things-factory/env'
|
4
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { User, UserStatus } from '../service/user/user'
|
7
|
-
|
8
|
-
const ADMIN_ACCOUNT = config.get('adminAccount', {
|
9
|
-
username: 'admin',
|
10
|
-
name: 'Admin',
|
11
|
-
email: 'admin@hatiolab.com',
|
12
|
-
password: 'admin'
|
13
|
-
})
|
14
|
-
|
15
|
-
const SEED_USERS = [
|
16
|
-
{
|
17
|
-
...ADMIN_ACCOUNT,
|
18
|
-
userType: 'user',
|
19
|
-
status: UserStatus.ACTIVATED
|
20
|
-
}
|
21
|
-
]
|
22
|
-
export class SeedUsers1548206416130 implements MigrationInterface {
|
23
|
-
public async up(queryRunner: QueryRunner): Promise<any> {
|
24
|
-
const userRepository = getRepository(User)
|
25
|
-
const domainRepository = getRepository(Domain)
|
26
|
-
|
27
|
-
const domain: Domain = await domainRepository.findOne({ where: { name: 'SYSTEM' } })
|
28
|
-
|
29
|
-
try {
|
30
|
-
for (let i = 0; i < SEED_USERS.length; i++) {
|
31
|
-
const user = SEED_USERS[i]
|
32
|
-
const salt = User.generateSalt()
|
33
|
-
const password = User.encode(user.password, salt)
|
34
|
-
|
35
|
-
await userRepository.save({
|
36
|
-
...user,
|
37
|
-
salt,
|
38
|
-
password,
|
39
|
-
domains: [domain]
|
40
|
-
})
|
41
|
-
}
|
42
|
-
} catch (e) {
|
43
|
-
logger.error(e)
|
44
|
-
}
|
45
|
-
|
46
|
-
const admin = await userRepository.findOne({ where: { email: ILike(ADMIN_ACCOUNT.email) } })
|
47
|
-
domain.owner = admin.id
|
48
|
-
|
49
|
-
await domainRepository.save(domain)
|
50
|
-
}
|
51
|
-
|
52
|
-
public async down(queryRunner: QueryRunner): Promise<any> {
|
53
|
-
const repository = getRepository(User)
|
54
|
-
|
55
|
-
SEED_USERS.reverse().forEach(async user => {
|
56
|
-
let record = await repository.findOneBy({ email: ILike(user.email) })
|
57
|
-
await repository.remove(record)
|
58
|
-
})
|
59
|
-
}
|
60
|
-
}
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import { MigrationInterface, QueryRunner } from 'typeorm'
|
2
|
-
|
3
|
-
import { logger } from '@things-factory/env'
|
4
|
-
import { getRepository } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { Privilege } from '../service/privilege/privilege'
|
7
|
-
|
8
|
-
export class SeedPrivilege1566805283882 implements MigrationInterface {
|
9
|
-
public async up(queryRunner: QueryRunner): Promise<any> {
|
10
|
-
const privilegeRepository = getRepository(Privilege)
|
11
|
-
|
12
|
-
const { schema } = require('@things-factory/shell/dist-server/schema')
|
13
|
-
await schema()
|
14
|
-
const privileges = process['PRIVILEGES']
|
15
|
-
|
16
|
-
try {
|
17
|
-
for (const [category, name] of Object.values(privileges as [string, string])) {
|
18
|
-
if (0 == (await privilegeRepository.count({ where: { category, name } }))) {
|
19
|
-
await privilegeRepository.save({ category, name })
|
20
|
-
}
|
21
|
-
}
|
22
|
-
} catch (e) {
|
23
|
-
logger.error(e)
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
public async down(queryRunner: QueryRunner): Promise<any> {}
|
28
|
-
}
|
@@ -1,9 +0,0 @@
|
|
1
|
-
const glob = require('glob')
|
2
|
-
const path = require('path')
|
3
|
-
|
4
|
-
export var migrations = []
|
5
|
-
|
6
|
-
glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function(file) {
|
7
|
-
if (file.indexOf('index.js') !== -1) return
|
8
|
-
migrations = migrations.concat(Object.values(require(path.resolve(file))) || [])
|
9
|
-
})
|
@@ -1,113 +0,0 @@
|
|
1
|
-
import Router from 'koa-router'
|
2
|
-
|
3
|
-
import { config } from '@things-factory/env'
|
4
|
-
import { Domain, findSubdomainFromPath, getRedirectSubdomainPath } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { LoginHistory } from '../service/login-history/login-history'
|
7
|
-
import { User } from '../service/user/user'
|
8
|
-
import { accepts } from '../utils/accepts'
|
9
|
-
import { clearAccessTokenCookie } from '../utils/access-token-cookie'
|
10
|
-
import { getUserDomains } from '../utils/get-user-domains'
|
11
|
-
|
12
|
-
const domainType = config.get('domainType')
|
13
|
-
|
14
|
-
export const authCheckinRouter = new Router()
|
15
|
-
|
16
|
-
authCheckinRouter.get('/auth/checkin/:subdomain?', async (context, next) => {
|
17
|
-
const { request, t } = context
|
18
|
-
const header = request.header
|
19
|
-
const { user } = context.state
|
20
|
-
let { subdomain } = context.params
|
21
|
-
|
22
|
-
let domains: Partial<Domain>[] = await getUserDomains(user)
|
23
|
-
if (domainType) domains = domains.filter(d => d.extType == domainType)
|
24
|
-
|
25
|
-
if (!accepts(header.accept, ['text/html', '*/*'])) {
|
26
|
-
// When request expects non html response
|
27
|
-
try {
|
28
|
-
if (!subdomain) throw new Error(t('error.domain not specified', { subdomain })) // When params doesn't have subdomain
|
29
|
-
const checkInDomain: Partial<Domain> | undefined = domains.find(d => d.subdomain === subdomain) // When no matched domain with subdomain
|
30
|
-
if (!checkInDomain) throw new Error(t('error.domain not specified', { subdomain }))
|
31
|
-
|
32
|
-
await checkIn(checkInDomain, null, context)
|
33
|
-
context.body = true
|
34
|
-
} catch (e) {
|
35
|
-
clearAccessTokenCookie(context)
|
36
|
-
throw e
|
37
|
-
}
|
38
|
-
} else {
|
39
|
-
// When request expects html response
|
40
|
-
const { redirect_to: redirectTo = '/' } = context.query
|
41
|
-
|
42
|
-
try {
|
43
|
-
let message: string
|
44
|
-
|
45
|
-
if (!subdomain) {
|
46
|
-
/* try to find domain from redirectTo path */
|
47
|
-
subdomain = findSubdomainFromPath(context, redirectTo)
|
48
|
-
}
|
49
|
-
|
50
|
-
let checkInDomain: Partial<Domain>
|
51
|
-
if (subdomain) {
|
52
|
-
checkInDomain = domains.find(d => d.subdomain == subdomain)
|
53
|
-
if (!checkInDomain) message = t('error.domain not allowed', { subdomain })
|
54
|
-
} else if (domains.length === 1) {
|
55
|
-
checkInDomain = domains[0]
|
56
|
-
}
|
57
|
-
|
58
|
-
if (checkInDomain) {
|
59
|
-
return await checkIn(checkInDomain, redirectTo, context)
|
60
|
-
}
|
61
|
-
|
62
|
-
await context.render('auth-page', {
|
63
|
-
pageElement: 'auth-checkin',
|
64
|
-
elementScript: '/auth/checkin.js',
|
65
|
-
data: {
|
66
|
-
user: {
|
67
|
-
username: user.username,
|
68
|
-
email: user.email,
|
69
|
-
locale: user.locale,
|
70
|
-
name: user.name,
|
71
|
-
userType: user.userType
|
72
|
-
},
|
73
|
-
domains,
|
74
|
-
domainType,
|
75
|
-
redirectTo,
|
76
|
-
message
|
77
|
-
}
|
78
|
-
})
|
79
|
-
} catch (e) {
|
80
|
-
clearAccessTokenCookie(context)
|
81
|
-
context.redirect(
|
82
|
-
`/auth/signin?username=${encodeURIComponent(user.username)}&redirect_to=${encodeURIComponent(redirectTo)}`
|
83
|
-
)
|
84
|
-
}
|
85
|
-
}
|
86
|
-
})
|
87
|
-
|
88
|
-
authCheckinRouter.get('/auth/domains', async context => {
|
89
|
-
const { user } = context.state
|
90
|
-
var domains = await getUserDomains(user)
|
91
|
-
if (domainType) {
|
92
|
-
domains = domains.filter(d => d.extType == domainType)
|
93
|
-
}
|
94
|
-
|
95
|
-
context.body = domains
|
96
|
-
})
|
97
|
-
|
98
|
-
async function checkIn(
|
99
|
-
checkInDomain: Partial<Domain>,
|
100
|
-
redirectTo: string | null,
|
101
|
-
context: ResolverContext
|
102
|
-
): Promise<void> {
|
103
|
-
const { user }: { user: User } = context.state
|
104
|
-
const remoteAddress = context.req.headers['x-forwarded-for']
|
105
|
-
? (context.req.headers['x-forwarded-for'] as string).split(',')[0].trim()
|
106
|
-
: context.req.connection.remoteAddress
|
107
|
-
|
108
|
-
await LoginHistory.stamp(checkInDomain, user, remoteAddress)
|
109
|
-
|
110
|
-
if (redirectTo) {
|
111
|
-
return context.redirect(getRedirectSubdomainPath(context, checkInDomain.subdomain, redirectTo))
|
112
|
-
}
|
113
|
-
}
|
@@ -1,114 +0,0 @@
|
|
1
|
-
import { ILike } from 'typeorm'
|
2
|
-
import Router from 'koa-router'
|
3
|
-
|
4
|
-
import { config } from '@things-factory/env'
|
5
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
6
|
-
|
7
|
-
import { changePwd } from '../controllers/change-pwd'
|
8
|
-
import { deleteUser } from '../controllers/delete-user'
|
9
|
-
import { updateProfile } from '../controllers/profile'
|
10
|
-
import { User } from '../service/user/user'
|
11
|
-
import { clearAccessTokenCookie, setAccessTokenCookie } from '../utils/access-token-cookie'
|
12
|
-
import { getUserDomains } from '../utils/get-user-domains'
|
13
|
-
|
14
|
-
const domainType = config.get('domainType')
|
15
|
-
const languages = config.get('i18n/languages') || []
|
16
|
-
|
17
|
-
export const authPrivateProcessRouter = new Router({
|
18
|
-
prefix: '/auth'
|
19
|
-
})
|
20
|
-
|
21
|
-
authPrivateProcessRouter
|
22
|
-
.post('/change-pass', async (context, next) => {
|
23
|
-
const { t } = context
|
24
|
-
let { current_pass, new_pass, confirm_pass } = context.request.body
|
25
|
-
|
26
|
-
const token = await changePwd(context.state.user, current_pass, new_pass, confirm_pass, context)
|
27
|
-
|
28
|
-
context.body = t('text.password changed successfully')
|
29
|
-
|
30
|
-
setAccessTokenCookie(context, token)
|
31
|
-
})
|
32
|
-
.post('/update-profile', async (context, next) => {
|
33
|
-
const { i18next, t } = context
|
34
|
-
const newProfiles = context.request.body
|
35
|
-
await updateProfile(context.state.user, newProfiles)
|
36
|
-
|
37
|
-
if (newProfiles.locale) {
|
38
|
-
context.body = i18next.getFixedT(newProfiles.locale)('text.profile changed successfully')
|
39
|
-
} else {
|
40
|
-
context.body = t('text.profile changed successfully')
|
41
|
-
}
|
42
|
-
})
|
43
|
-
.post('/delete-user', async (context, next) => {
|
44
|
-
const { t, session } = context
|
45
|
-
var { user } = context.state
|
46
|
-
var { id: userId } = user
|
47
|
-
|
48
|
-
var { password, username } = context.request.body
|
49
|
-
|
50
|
-
const userRepo = getRepository(User)
|
51
|
-
|
52
|
-
var userInfo = await userRepo.findOne({
|
53
|
-
where: { username },
|
54
|
-
relations: ['domains']
|
55
|
-
})
|
56
|
-
|
57
|
-
if (!userInfo && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
58
|
-
userInfo = await userRepo.findOne({
|
59
|
-
where: { email: ILike(username) },
|
60
|
-
relations: ['domains']
|
61
|
-
})
|
62
|
-
}
|
63
|
-
|
64
|
-
if (userInfo.id != userId || !User.verify(userInfo.password, password, userInfo.salt)) {
|
65
|
-
context.status = 401
|
66
|
-
context.body = t('error.user validation failed')
|
67
|
-
return
|
68
|
-
}
|
69
|
-
|
70
|
-
await deleteUser(user)
|
71
|
-
|
72
|
-
context.body = t('text.delete account succeed')
|
73
|
-
clearAccessTokenCookie(context)
|
74
|
-
})
|
75
|
-
.get('/profile', async (context, next) => {
|
76
|
-
const { t } = context
|
77
|
-
const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
|
78
|
-
|
79
|
-
if (!domain) {
|
80
|
-
context.status = 401
|
81
|
-
context.body = t('error.user validation failed')
|
82
|
-
return
|
83
|
-
}
|
84
|
-
|
85
|
-
let domains: Partial<Domain>[] = await getUserDomains(user)
|
86
|
-
domains = domains.filter((d: Domain) => d.extType == domainType)
|
87
|
-
|
88
|
-
var privileges = await User.getPrivilegesByDomain(user, domain)
|
89
|
-
|
90
|
-
if (prohibitedPrivileges) {
|
91
|
-
prohibitedPrivileges.forEach(({ category, privilege }) => {
|
92
|
-
privileges = privileges.filter(p => p.category != category || p.privilege != privilege)
|
93
|
-
})
|
94
|
-
}
|
95
|
-
|
96
|
-
context.body = {
|
97
|
-
user: {
|
98
|
-
username: user.username,
|
99
|
-
email: user.email,
|
100
|
-
name: user.name,
|
101
|
-
userType: user.userType,
|
102
|
-
owner: await process.domainOwnerGranted(domain, user),
|
103
|
-
super: await process.superUserGranted(domain, user),
|
104
|
-
unsafeIP,
|
105
|
-
privileges
|
106
|
-
},
|
107
|
-
domains,
|
108
|
-
domain: domain && {
|
109
|
-
name: domain.name,
|
110
|
-
subdomain: domain.subdomain
|
111
|
-
},
|
112
|
-
languages
|
113
|
-
}
|
114
|
-
})
|