@things-factory/auth-base 9.0.0-beta.76 → 9.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/dist-client/auth.js +2 -4
- package/dist-client/auth.js.map +1 -1
- package/dist-client/reducers/auth.js +9 -2
- package/dist-client/reducers/auth.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/change-pwd.js +5 -2
- package/dist-server/controllers/change-pwd.js.map +1 -1
- package/dist-server/controllers/checkin.js +1 -1
- package/dist-server/controllers/checkin.js.map +1 -1
- package/dist-server/controllers/delete-user.js +2 -2
- package/dist-server/controllers/delete-user.js.map +1 -1
- package/dist-server/controllers/profile.js +4 -1
- package/dist-server/controllers/profile.js.map +1 -1
- package/dist-server/controllers/reset-password.js +5 -2
- package/dist-server/controllers/reset-password.js.map +1 -1
- package/dist-server/controllers/signin.js +2 -2
- package/dist-server/controllers/signin.js.map +1 -1
- package/dist-server/controllers/signup.js +8 -1
- package/dist-server/controllers/signup.js.map +1 -1
- package/dist-server/errors/auth-error.js +3 -1
- package/dist-server/errors/auth-error.js.map +1 -1
- package/dist-server/middlewares/authenticate-401-middleware.js +22 -9
- package/dist-server/middlewares/authenticate-401-middleware.js.map +1 -1
- package/dist-server/middlewares/domain-authenticate-middleware.js +1 -1
- package/dist-server/middlewares/domain-authenticate-middleware.js.map +1 -1
- package/dist-server/middlewares/jwt-authenticate-middleware.js +1 -1
- package/dist-server/middlewares/jwt-authenticate-middleware.js.map +1 -1
- package/dist-server/migrations/1548206416130-SeedUser.js +11 -3
- package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
- package/dist-server/router/auth-signup-router.js +5 -2
- package/dist-server/router/auth-signup-router.js.map +1 -1
- package/dist-server/router/oauth2/oauth2-authorize-router.js +5 -2
- package/dist-server/router/oauth2/oauth2-authorize-router.js.map +1 -1
- package/dist-server/router/oauth2/oauth2-router.js +1 -2
- package/dist-server/router/oauth2/oauth2-router.js.map +1 -1
- package/dist-server/router/oauth2/oauth2-server.js +21 -3
- package/dist-server/router/oauth2/oauth2-server.js.map +1 -1
- package/dist-server/router/site-root-router.js +1 -1
- package/dist-server/router/site-root-router.js.map +1 -1
- package/dist-server/router/webauthn-router.js +1 -1
- package/dist-server/router/webauthn-router.js.map +1 -1
- package/dist-server/service/app-binding/app-binding-types.js +3 -3
- package/dist-server/service/app-binding/app-binding-types.js.map +1 -1
- package/dist-server/service/app-binding/app-binding.js +6 -4
- package/dist-server/service/app-binding/app-binding.js.map +1 -1
- package/dist-server/service/appliance/appliance-mutation.js +20 -4
- package/dist-server/service/appliance/appliance-mutation.js.map +1 -1
- package/dist-server/service/appliance/appliance-types.js +18 -18
- package/dist-server/service/appliance/appliance-types.js.map +1 -1
- package/dist-server/service/appliance/appliance.js +22 -18
- package/dist-server/service/appliance/appliance.js.map +1 -1
- package/dist-server/service/application/application-mutation.js +22 -4
- package/dist-server/service/application/application-mutation.js.map +1 -1
- package/dist-server/service/application/application-types.js +24 -24
- package/dist-server/service/application/application-types.js.map +1 -1
- package/dist-server/service/application/application.d.ts +6 -6
- package/dist-server/service/application/application.js +22 -22
- package/dist-server/service/application/application.js.map +1 -1
- package/dist-server/service/auth-provider/auth-provider-mutation.js +29 -7
- package/dist-server/service/auth-provider/auth-provider-mutation.js.map +1 -1
- package/dist-server/service/auth-provider/auth-provider-parameter-spec.js +12 -7
- package/dist-server/service/auth-provider/auth-provider-parameter-spec.js.map +1 -1
- package/dist-server/service/auth-provider/auth-provider-type.js +24 -21
- package/dist-server/service/auth-provider/auth-provider-type.js.map +1 -1
- package/dist-server/service/auth-provider/auth-provider.js +35 -25
- package/dist-server/service/auth-provider/auth-provider.js.map +1 -1
- package/dist-server/service/domain-generator/domain-generator-mutation.js +1 -2
- package/dist-server/service/domain-generator/domain-generator-mutation.js.map +1 -1
- package/dist-server/service/domain-generator/domain-generator-types.js +17 -14
- package/dist-server/service/domain-generator/domain-generator-types.js.map +1 -1
- package/dist-server/service/domain-link/domain-link-mutation.js +23 -6
- package/dist-server/service/domain-link/domain-link-mutation.js.map +1 -1
- package/dist-server/service/domain-link/domain-link-types.js +13 -13
- package/dist-server/service/domain-link/domain-link-types.js.map +1 -1
- package/dist-server/service/domain-link/domain-link.d.ts +2 -2
- package/dist-server/service/domain-link/domain-link.js +11 -11
- package/dist-server/service/domain-link/domain-link.js.map +1 -1
- package/dist-server/service/granted-role/granted-role-mutation.js +7 -7
- package/dist-server/service/granted-role/granted-role-mutation.js.map +1 -1
- package/dist-server/service/granted-role/granted-role.js +4 -4
- package/dist-server/service/granted-role/granted-role.js.map +1 -1
- package/dist-server/service/invitation/invitation-mutation.js +6 -2
- package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
- package/dist-server/service/invitation/invitation-types.js +3 -3
- package/dist-server/service/invitation/invitation-types.js.map +1 -1
- package/dist-server/service/invitation/invitation.js +10 -10
- package/dist-server/service/invitation/invitation.js.map +1 -1
- package/dist-server/service/login-history/login-history-type.js +3 -3
- package/dist-server/service/login-history/login-history-type.js.map +1 -1
- package/dist-server/service/login-history/login-history.js +6 -6
- package/dist-server/service/login-history/login-history.js.map +1 -1
- package/dist-server/service/partner/partner-types.js +3 -3
- package/dist-server/service/partner/partner-types.js.map +1 -1
- package/dist-server/service/partner/partner.js +8 -8
- package/dist-server/service/partner/partner.js.map +1 -1
- package/dist-server/service/password-history/password-history.js +3 -3
- package/dist-server/service/password-history/password-history.js.map +1 -1
- package/dist-server/service/privilege/privilege-directive.js +1 -2
- package/dist-server/service/privilege/privilege-directive.js.map +1 -1
- package/dist-server/service/privilege/privilege-mutation.js +11 -2
- package/dist-server/service/privilege/privilege-mutation.js.map +1 -1
- package/dist-server/service/privilege/privilege.js +20 -20
- package/dist-server/service/privilege/privilege.js.map +1 -1
- package/dist-server/service/role/role-mutation.js +12 -2
- package/dist-server/service/role/role-mutation.js.map +1 -1
- package/dist-server/service/role/role-query.js +1 -1
- package/dist-server/service/role/role-query.js.map +1 -1
- package/dist-server/service/role/role-types.js +29 -29
- package/dist-server/service/role/role-types.js.map +1 -1
- package/dist-server/service/role/role.js +11 -11
- package/dist-server/service/role/role.js.map +1 -1
- package/dist-server/service/user/user-mutation.js +89 -41
- package/dist-server/service/user/user-mutation.js.map +1 -1
- package/dist-server/service/user/user-query.js +16 -10
- package/dist-server/service/user/user-query.js.map +1 -1
- package/dist-server/service/user/user-types.js +33 -32
- package/dist-server/service/user/user-types.js.map +1 -1
- package/dist-server/service/user/user.d.ts +5 -5
- package/dist-server/service/user/user.js +25 -22
- package/dist-server/service/user/user.js.map +1 -1
- package/dist-server/service/users-auth-providers/users-auth-providers.js +11 -8
- package/dist-server/service/users-auth-providers/users-auth-providers.js.map +1 -1
- package/dist-server/service/verification-token/verification-token.d.ts +3 -3
- package/dist-server/service/verification-token/verification-token.js +8 -8
- package/dist-server/service/verification-token/verification-token.js.map +1 -1
- package/dist-server/service/web-auth-credential/web-auth-credential.js +11 -10
- package/dist-server/service/web-auth-credential/web-auth-credential.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/utils/access-token-cookie.js +1 -2
- package/dist-server/utils/access-token-cookie.js.map +1 -1
- package/dist-server/utils/check-user-belongs-domain.js +1 -2
- package/dist-server/utils/check-user-belongs-domain.js.map +1 -1
- package/dist-server/utils/get-domain-users.js +2 -2
- package/dist-server/utils/get-domain-users.js.map +1 -1
- package/package.json +6 -6
@@ -7,7 +7,7 @@ const unlock_user_js_1 = require("../controllers/unlock-user.js");
|
|
7
7
|
const auth_error_js_1 = require("../errors/auth-error.js");
|
8
8
|
const user_js_1 = require("../service/user/user.js");
|
9
9
|
async function signin(attrs, context) {
|
10
|
-
const { domain } =
|
10
|
+
const { domain } = context?.state || {};
|
11
11
|
const { username } = attrs;
|
12
12
|
const repository = (0, shell_1.getRepository)(user_js_1.User);
|
13
13
|
var user = await repository.findOne({
|
@@ -86,7 +86,7 @@ async function signin(attrs, context) {
|
|
86
86
|
}
|
87
87
|
return {
|
88
88
|
user,
|
89
|
-
token: await user.sign({ subdomain: domain
|
89
|
+
token: await user.sign({ subdomain: domain?.subdomain }),
|
90
90
|
domains: user.domains || []
|
91
91
|
};
|
92
92
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"signin.js","sourceRoot":"","sources":["../../server/controllers/signin.ts"],"names":[],"mappings":";;AAOA,wBA0FC;AAjGD,qCAA+B;AAC/B,iDAAqD;AAErD,kEAAmE;AACnE,2DAAmD;AACnD,qDAA0D;AAEnD,KAAK,UAAU,MAAM,CAAC,KAA6C,EAAE,OAAQ;IAClF,MAAM,EAAE,MAAM,EAAE,GAAG,
|
1
|
+
{"version":3,"file":"signin.js","sourceRoot":"","sources":["../../server/controllers/signin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILike } from 'typeorm'\nimport { getRepository } from '@things-factory/shell'\n\nimport { sendUnlockUserEmail } from '../controllers/unlock-user.js'\nimport { AuthError } from '../errors/auth-error.js'\nimport { User, UserStatus } from '../service/user/user.js'\n\nexport async function signin(attrs: { username: string; password: string }, context?) {\n const { domain } = context?.state || {}\n const { username } = attrs\n\n const repository = getRepository(User)\n\n var user = await repository.findOne({\n where: { username },\n relations: ['domains']\n })\n\n if (!user && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(username)) {\n user = await repository.findOne({\n where: {\n email: ILike(username)\n },\n relations: ['domains']\n })\n }\n\n if (!user)\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.USER_NOT_FOUND\n })\n\n if (user.status == UserStatus.DELETED) {\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.USER_DELETED\n })\n }\n\n if (user.status == UserStatus.LOCKED) {\n sendUnlockUserEmail({\n user,\n context\n })\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.USER_LOCKED,\n detail: {\n username: user.username,\n email: user.email\n }\n })\n }\n\n if (!User.verify(user.password, attrs.password, user.salt)) {\n user.failCount++\n if (user.failCount >= 5) user.status = UserStatus.LOCKED\n await repository.save(user)\n if (user.status == UserStatus.LOCKED) {\n sendUnlockUserEmail({\n user,\n context\n })\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.USER_LOCKED,\n detail: {\n username: user.username,\n email: user.email\n }\n })\n }\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.PASSWORD_NOT_MATCHED,\n detail: {\n username: user.username,\n email: user.email,\n failCount: user.failCount\n }\n })\n } else {\n user.failCount = 0\n await repository.save(user)\n }\n\n if (user.status == UserStatus.INACTIVE) {\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.USER_NOT_ACTIVATED,\n detail: {\n username: user.username,\n email: user.email\n }\n })\n }\n\n return {\n user,\n token: await user.sign({ subdomain: domain?.subdomain }),\n domains: user.domains || []\n }\n}\n"]}
|
@@ -33,7 +33,14 @@ async function signup(attrs, withEmailVerification) {
|
|
33
33
|
});
|
34
34
|
}
|
35
35
|
const salt = user_js_1.User.generateSalt();
|
36
|
-
var user = await repository.save(
|
36
|
+
var user = await repository.save({
|
37
|
+
userType: 'user',
|
38
|
+
...attrs,
|
39
|
+
salt,
|
40
|
+
password: user_js_1.User.encode(password, salt),
|
41
|
+
passwordUpdatedAt: new Date(),
|
42
|
+
domains: domain ? [domain] : []
|
43
|
+
});
|
37
44
|
var succeed = false;
|
38
45
|
if (withEmailVerification) {
|
39
46
|
succeed = await (0, verification_js_1.sendVerificationEmail)({
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../server/controllers/signup.ts"],"names":[],"mappings":";;AASA,wBA8DC;AAvED,qCAA+B;AAC/B,iDAAqD;AAErD,8DAA4D;AAC5D,2DAAmD;AACnD,qDAA8C;AAC9C,2CAAoC;AACpC,uDAAyD;AAElD,KAAK,UAAU,MAAM,CAAC,KAAK,EAAE,qBAA+B;IACjE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;IAE3D,6CAA6C;IAC7C,cAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAElD,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAA;IAEtC,IAAI,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;QACxC,KAAK,EAAE,EAAE,QAAQ,EAAE;QACnB,SAAS,EAAE,CAAC,SAAS,CAAC;KACvB,CAAC,CAAA;IAEF,IAAI,CAAC,UAAU,IAAI,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/D,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;YAC9B,KAAK,EAAE,EAAE,KAAK,EAAE,IAAA,eAAK,EAAC,QAAQ,CAAC,EAAE;YACjC,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,IAAI,yBAAS,CAAC;YAClB,SAAS,EAAE,+BAAe;YAC1B,MAAM,EAAE;gBACN,IAAI;gBACJ,QAAQ;aACT;SACF,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,cAAI,CAAC,YAAY,EAAE,CAAA;IAEhC,IAAI,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI
|
1
|
+
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../server/controllers/signup.ts"],"names":[],"mappings":";;AASA,wBA8DC;AAvED,qCAA+B;AAC/B,iDAAqD;AAErD,8DAA4D;AAC5D,2DAAmD;AACnD,qDAA8C;AAC9C,2CAAoC;AACpC,uDAAyD;AAElD,KAAK,UAAU,MAAM,CAAC,KAAK,EAAE,qBAA+B;IACjE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;IAE3D,6CAA6C;IAC7C,cAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAElD,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAA;IAEtC,IAAI,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;QACxC,KAAK,EAAE,EAAE,QAAQ,EAAE;QACnB,SAAS,EAAE,CAAC,SAAS,CAAC;KACvB,CAAC,CAAA;IAEF,IAAI,CAAC,UAAU,IAAI,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/D,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;YAC9B,KAAK,EAAE,EAAE,KAAK,EAAE,IAAA,eAAK,EAAC,QAAQ,CAAC,EAAE;YACjC,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,IAAI,yBAAS,CAAC;YAClB,SAAS,EAAE,+BAAe;YAC1B,MAAM,EAAE;gBACN,IAAI;gBACJ,QAAQ;aACT;SACF,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,cAAI,CAAC,YAAY,EAAE,CAAA;IAEhC,IAAI,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;QAC/B,QAAQ,EAAE,MAAM;QAChB,GAAG,KAAK;QACR,IAAI;QACJ,QAAQ,EAAE,cAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC;QACrC,iBAAiB,EAAE,IAAI,IAAI,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;KAChC,CAAC,CAAA;IAEF,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,qBAAqB,EAAE,CAAC;QAC1B,OAAO,GAAG,MAAM,IAAA,uCAAqB,EAAC;YACpC,OAAO;YACP,IAAI;SACL,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO;YACL,KAAK,EAAE,MAAM,IAAA,kBAAM,EACjB;gBACE,QAAQ;gBACR,QAAQ;aACT,EACD,EAAE,MAAM,EAAE,CACX;SACF,CAAA;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;AACH,CAAC","sourcesContent":["import { ILike } from 'typeorm'\nimport { getRepository } from '@things-factory/shell'\n\nimport { USER_DUPLICATED } from '../constants/error-code.js'\nimport { AuthError } from '../errors/auth-error.js'\nimport { User } from '../service/user/user.js'\nimport { signin } from './signin.js'\nimport { sendVerificationEmail } from './verification.js'\n\nexport async function signup(attrs, withEmailVerification?: Boolean) {\n const { name, username, password, domain, context } = attrs\n\n /* check if password is following the rule */\n User.validatePasswordByRule(password, context.lng)\n\n const repository = getRepository(User)\n\n var duplicated = await repository.findOne({\n where: { username },\n relations: ['domains']\n })\n\n if (!duplicated && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(username)) {\n user = await repository.findOne({\n where: { email: ILike(username) },\n relations: ['domains']\n })\n }\n\n if (duplicated) {\n throw new AuthError({\n errorCode: USER_DUPLICATED,\n detail: {\n name,\n username\n }\n })\n }\n\n const salt = User.generateSalt()\n\n var user = await repository.save({\n userType: 'user',\n ...attrs,\n salt,\n password: User.encode(password, salt),\n passwordUpdatedAt: new Date(),\n domains: domain ? [domain] : []\n })\n\n var succeed = false\n if (withEmailVerification) {\n succeed = await sendVerificationEmail({\n context,\n user\n })\n }\n\n try {\n return {\n token: await signin(\n {\n username,\n password\n },\n { domain }\n )\n }\n } catch (e) {\n return { token: null }\n }\n}\n"]}
|
@@ -5,7 +5,9 @@ const tslib_1 = require("tslib");
|
|
5
5
|
const ERROR_CODES = tslib_1.__importStar(require("../constants/error-code.js"));
|
6
6
|
class AuthError extends Error {
|
7
7
|
static get ERROR_CODES() {
|
8
|
-
return
|
8
|
+
return {
|
9
|
+
...ERROR_CODES
|
10
|
+
};
|
9
11
|
}
|
10
12
|
constructor({ errorCode, detail }) {
|
11
13
|
super(errorCode);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"auth-error.js","sourceRoot":"","sources":["../../server/errors/auth-error.ts"],"names":[],"mappings":";;;;AAAA,gFAAyD;AAMzD,MAAa,SAAU,SAAQ,KAAK;IAClC,MAAM,KAAK,WAAW;QACpB,
|
1
|
+
{"version":3,"file":"auth-error.js","sourceRoot":"","sources":["../../server/errors/auth-error.ts"],"names":[],"mappings":";;;;AAAA,gFAAyD;AAMzD,MAAa,SAAU,SAAQ,KAAK;IAClC,MAAM,KAAK,WAAW;QACpB,OAAO;YACL,GAAG,WAAW;SACf,CAAA;IACH,CAAC;IAKD,YAAY,EAAE,SAAS,EAAE,MAAM,EAAqB;QAClD,KAAK,CAAC,SAAS,CAAC,CAAA;QAEhB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;QACxB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAjBD,8BAiBC","sourcesContent":["import * as ERROR_CODES from '../constants/error-code.js'\n\ntype AuthErrorArgument = {\n errorCode: string\n detail?: Object\n}\nexport class AuthError extends Error {\n static get ERROR_CODES(): any {\n return {\n ...ERROR_CODES\n }\n }\n\n errorCode: any\n detail: Object\n\n constructor({ errorCode, detail }: AuthErrorArgument) {\n super(errorCode)\n\n this.name = 'auth-error'\n this.errorCode = errorCode\n this.detail = detail\n }\n}\n"]}
|
@@ -18,7 +18,7 @@ async function authenticate401Middleware(context, next) {
|
|
18
18
|
message = (context.t && context.t(`error.${err.errorCode}`, err.detail || {})) || err.errorCode;
|
19
19
|
}
|
20
20
|
else {
|
21
|
-
if (
|
21
|
+
if (err?.status !== 401) {
|
22
22
|
throw err;
|
23
23
|
}
|
24
24
|
message = err.message;
|
@@ -50,40 +50,53 @@ async function authenticate401Middleware(context, next) {
|
|
50
50
|
return await context.render('auth-page', {
|
51
51
|
pageElement: 'auth-activate',
|
52
52
|
elementScript: '/auth/activate.js',
|
53
|
-
data:
|
53
|
+
data: {
|
54
|
+
...err.detail,
|
55
|
+
message,
|
54
56
|
redirectTo,
|
55
57
|
disableUserSignupProcess,
|
56
58
|
disableUserFavoredLanguage,
|
57
|
-
languages
|
59
|
+
languages
|
60
|
+
}
|
58
61
|
});
|
59
62
|
case error_code_js_1.USER_NOT_ACTIVATED:
|
60
63
|
return await context.render('auth-page', {
|
61
64
|
pageElement: 'auth-activate',
|
62
65
|
elementScript: '/auth/activate.js',
|
63
|
-
data:
|
66
|
+
data: {
|
67
|
+
...err.detail,
|
68
|
+
message,
|
64
69
|
redirectTo,
|
65
70
|
disableUserSignupProcess,
|
66
71
|
disableUserFavoredLanguage,
|
67
|
-
languages
|
72
|
+
languages
|
73
|
+
}
|
68
74
|
});
|
69
75
|
case error_code_js_1.USER_DUPLICATED:
|
70
76
|
return await context.render('auth-page', {
|
71
77
|
pageElement: 'auth-signup',
|
72
78
|
elementScript: '/auth/signup.js',
|
73
|
-
data:
|
79
|
+
data: {
|
80
|
+
...err.detail,
|
81
|
+
message,
|
74
82
|
redirectTo,
|
75
83
|
disableUserSignupProcess,
|
76
84
|
disableUserFavoredLanguage,
|
77
|
-
languages
|
85
|
+
languages
|
86
|
+
}
|
78
87
|
});
|
79
88
|
default:
|
80
89
|
return await context.render('auth-page', {
|
81
90
|
pageElement: 'auth-signin',
|
82
91
|
elementScript: '/auth/signin.js',
|
83
|
-
data:
|
92
|
+
data: {
|
93
|
+
...err.detail,
|
94
|
+
message: err instanceof auth_error_js_1.AuthError ? message : '',
|
95
|
+
redirectTo,
|
84
96
|
disableUserSignupProcess,
|
85
97
|
disableUserFavoredLanguage,
|
86
|
-
languages
|
98
|
+
languages
|
99
|
+
}
|
87
100
|
});
|
88
101
|
}
|
89
102
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"authenticate-401-middleware.js","sourceRoot":"","sources":["../../server/middlewares/authenticate-401-middleware.ts"],"names":[],"mappings":";;AAUA,8DAuGC;AAjHD,6CAA4C;AAE5C,8DAAiH;AACjH,2DAAmD;AACnD,oDAA6C;AAE7C,MAAM,wBAAwB,GAAG,YAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;AAC9E,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AAE9C,KAAK,UAAU,yBAAyB,CAAC,OAAO,EAAE,IAAI;IAC3D,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,OAAO,CAAA;QAEX,IAAI,GAAG,YAAY,yBAAS,EAAE,CAAC;YAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAA;QACjG,CAAC;aAAM,CAAC;YACN,IAAI,
|
1
|
+
{"version":3,"file":"authenticate-401-middleware.js","sourceRoot":"","sources":["../../server/middlewares/authenticate-401-middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import { config } from '@things-factory/env'\n\nimport { SUBDOMAIN_NOTFOUND, USER_DUPLICATED, USER_LOCKED, USER_NOT_ACTIVATED } from '../constants/error-code.js'\nimport { AuthError } from '../errors/auth-error.js'\nimport { accepts } from '../utils/accepts.js'\n\nconst disableUserSignupProcess = config.get('disableUserSignupProcess', false)\nconst disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)\nconst languages = config.get('i18n/languages', false)\n\nexport async function authenticate401Middleware(context, next) {\n try {\n await next()\n } catch (err) {\n var message\n\n if (err instanceof AuthError) {\n message = (context.t && context.t(`error.${err.errorCode}`, err.detail || {})) || err.errorCode\n } else {\n if (err?.status !== 401) {\n throw err\n }\n\n message = err.message\n }\n\n context.status = 401\n context.body = message\n\n /*\n * 클라이언트 라우팅을 위한 ApiHistoryFallback의 상황과,\n * 서버라우팅의 상황에서 발생하는 던져지는 401 에러인 경우에는\n * error code에 맞춰서 적절하게 rewriting 되도록 한다.\n */\n\n const { method, header, path, originalUrl } = context\n\n if (method == 'POST' && path.startsWith('/graphql')) {\n if (err.errorCode == SUBDOMAIN_NOTFOUND) {\n context.status = 403\n }\n return\n }\n\n if (!accepts(header.accept, ['text/html', '*/*'])) {\n return\n }\n\n const { redirect_to } = context.query\n const { redirectTo = redirect_to || originalUrl } = context.request.body || {}\n\n switch (err.errorCode) {\n case SUBDOMAIN_NOTFOUND:\n context.redirect(`/auth/checkin?redirect_to=${encodeURIComponent(redirectTo)}`)\n break\n\n case USER_LOCKED:\n return await context.render('auth-page', {\n pageElement: 'auth-activate',\n elementScript: '/auth/activate.js',\n data: {\n ...err.detail,\n message,\n redirectTo,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n\n case USER_NOT_ACTIVATED:\n return await context.render('auth-page', {\n pageElement: 'auth-activate',\n elementScript: '/auth/activate.js',\n data: {\n ...err.detail,\n message,\n redirectTo,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n\n case USER_DUPLICATED:\n return await context.render('auth-page', {\n pageElement: 'auth-signup',\n elementScript: '/auth/signup.js',\n data: {\n ...err.detail,\n message,\n redirectTo,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n\n default:\n return await context.render('auth-page', {\n pageElement: 'auth-signin',\n elementScript: '/auth/signin.js',\n data: {\n ...err.detail,\n message: err instanceof AuthError ? message : '',\n redirectTo,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n }\n }\n}\n"]}
|
@@ -36,7 +36,7 @@ process.superUserGranted = async (domain, user) => {
|
|
36
36
|
async function domainAuthenticateMiddleware(context, next) {
|
37
37
|
const { t } = context;
|
38
38
|
const { domain, user } = context.state;
|
39
|
-
const subdomain = domain
|
39
|
+
const subdomain = domain?.subdomain;
|
40
40
|
// 1. 현재 subdomain 이 결정되지 않은 경우.
|
41
41
|
// - checkin로 이동한다.
|
42
42
|
if (!subdomain) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"domain-authenticate-middleware.js","sourceRoot":"","sources":["../../server/middlewares/domain-authenticate-middleware.ts"],"names":[],"mappings":";;AAiDA,oEAuBC;AAxED,iDAA6D;AAE7D,2DAAmD;AACnD,qDAA8C;AAC9C,sEAA6D;AAW7D,OAAO,CAAC,kBAAkB,GAAG,KAAK,EAAE,MAAc,EAAE,IAAU,EAAoB,EAAE;IAClF,OAAO,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAA;AACnD,CAAC,CAAA;AAED,OAAO,CAAC,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,IAAU,EAAoB,EAAE;IAChF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAC,OAAO,CAAC;YACvC,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,YAAY,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAA;IACjG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAA;AACvC,CAAC,CAAA;AAED;;;;;;;;GAQG;AAEI,KAAK,UAAU,4BAA4B,CAAC,OAAY,EAAE,IAAS;IACxE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;IACrB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAEtC,MAAM,SAAS,GAAW,MAAM,
|
1
|
+
{"version":3,"file":"domain-authenticate-middleware.js","sourceRoot":"","sources":["../../server/middlewares/domain-authenticate-middleware.ts"],"names":[],"mappings":";;AAiDA,oEAuBC;AAxED,iDAA6D;AAE7D,2DAAmD;AACnD,qDAA8C;AAC9C,sEAA6D;AAW7D,OAAO,CAAC,kBAAkB,GAAG,KAAK,EAAE,MAAc,EAAE,IAAU,EAAoB,EAAE;IAClF,OAAO,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAA;AACnD,CAAC,CAAA;AAED,OAAO,CAAC,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,IAAU,EAAoB,EAAE;IAChF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAC,OAAO,CAAC;YACvC,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,YAAY,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAA;IACjG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAA;AACvC,CAAC,CAAA;AAED;;;;;;;;GAQG;AAEI,KAAK,UAAU,4BAA4B,CAAC,OAAY,EAAE,IAAS;IACxE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;IACrB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAEtC,MAAM,SAAS,GAAW,MAAM,EAAE,SAAS,CAAA;IAE3C,gCAAgC;IAChC,mBAAmB;IACnB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,yBAAS,CAAC;YAClB,SAAS,EAAE,yBAAS,CAAC,WAAW,CAAC,kBAAkB;SACpD,CAAC,CAAA;IACJ,CAAC;IAED,4BAA4B;IAC5B,MAAM,WAAW,GAAsB,MAAM,IAAA,oCAAc,EAAC,IAAI,CAAC,CAAA;IACjE,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAChH,OAAO,MAAM,IAAI,EAAE,CAAA;IACrB,CAAC;IAED,MAAM,IAAI,yBAAS,CAAC;QAClB,SAAS,EAAE,yBAAS,CAAC,WAAW,CAAC,kBAAkB;KACpD,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Domain, getRepository } from '@things-factory/shell'\n\nimport { AuthError } from '../errors/auth-error.js'\nimport { User } from '../service/user/user.js'\nimport { getUserDomains } from '../utils/get-user-domains.js'\n\ndeclare global {\n namespace NodeJS {\n interface Process {\n domainOwnerGranted: (domain: Domain, user: User) => Promise<boolean>\n superUserGranted: (domain: Domain, user: User) => Promise<boolean>\n }\n }\n}\n\nprocess.domainOwnerGranted = async (domain: Domain, user: User): Promise<boolean> => {\n return user && domain && domain.owner === user.id\n}\n\nprocess.superUserGranted = async (domain: Domain, user: User): Promise<boolean> => {\n if (!user) {\n return false\n }\n\n if (!user.domains.length) {\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['domains']\n })\n }\n\n const systemDomain: Domain = user.domains.find((domain: Domain) => domain.subdomain === 'system')\n if (!systemDomain) {\n return false\n }\n\n return systemDomain.owner === user.id\n}\n\n/*\n * 현재 subdomain 과 user의 domain list와의 비교를 통해서,\n * 인증 성공 또는 인증 에러를 발생시킬 것인지를 결정한다.\n * 1. 현재 subdomain 이 결정되지 않은 경우.\n * - checkin로 이동한다.\n * 2. superUser 판단\n * 3. 현재 subdomain 이 결정된 경우.\n * - user의 domains 리스트에 해당 subdomain이 없다면, 인증 오류를 발생한다.\n */\n\nexport async function domainAuthenticateMiddleware(context: any, next: any) {\n const { t } = context\n const { domain, user } = context.state\n\n const subdomain: string = domain?.subdomain\n\n // 1. 현재 subdomain 이 결정되지 않은 경우.\n // - checkin로 이동한다.\n if (!subdomain) {\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.SUBDOMAIN_NOTFOUND\n })\n }\n\n // 2. 현재 subdomain 이 결정된 경우.\n const userDomains: Partial<Domain>[] = await getUserDomains(user)\n if (userDomains.find(domain => domain.subdomain == subdomain) || (await process.superUserGranted(domain, user))) {\n return await next()\n }\n\n throw new AuthError({\n errorCode: AuthError.ERROR_CODES.SUBDOMAIN_NOTFOUND\n })\n}\n"]}
|
@@ -23,7 +23,7 @@ koa_passport_1.default.use(new passport_jwt_1.Strategy({
|
|
23
23
|
passport_jwt_1.ExtractJwt.fromBodyField('access_token'),
|
24
24
|
req => {
|
25
25
|
var token = null;
|
26
|
-
token = (0, access_token_cookie_js_1.getAccessTokenCookie)(req
|
26
|
+
token = (0, access_token_cookie_js_1.getAccessTokenCookie)(req?.ctx);
|
27
27
|
return token;
|
28
28
|
}
|
29
29
|
])
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"jwt-authenticate-middleware.js","sourceRoot":"","sources":["../../server/middlewares/jwt-authenticate-middleware.ts"],"names":[],"mappings":";;AA0CA,8DAyCC;;AAnFD,wEAAmC;AACnC,+CAAkE;AAElE,6CAA4C;AAE5C,gGAAuF;AACvF,gGAAuF;AACvF,qDAA0D;AAC1D,+FAA2F;AAC3F,4EAAoH;AACpH,0DAA+C;AAE/C,MAAM,mBAAmB,GAAG,YAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAA;AAEvE,sBAAQ,CAAC,GAAG,CACV,IAAI,uBAAW,CACb;IACE,WAAW,EAAE,sBAAM;IACnB,iBAAiB,EAAE,IAAI;IACvB,cAAc,EAAE,yBAAU,CAAC,cAAc,CAAC;QACxC,yBAAU,CAAC,2BAA2B,EAAE;QACxC,yBAAU,CAAC,UAAU,CAAC,eAAe,CAAC;QACtC,yBAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC;QACvC,yBAAU,CAAC,qBAAqB,CAAC,cAAc,CAAC;QAChD,yBAAU,CAAC,aAAa,CAAC,cAAc,CAAC;QACxC,GAAG,CAAC,EAAE;YACJ,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,GAAG,IAAA,6CAAoB,EAAC,GAAG,
|
1
|
+
{"version":3,"file":"jwt-authenticate-middleware.js","sourceRoot":"","sources":["../../server/middlewares/jwt-authenticate-middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import passport from 'koa-passport'\nimport { ExtractJwt, Strategy as JWTstrategy } from 'passport-jwt'\n\nimport { config } from '@things-factory/env'\n\nimport { makeVerificationToken } from '../controllers/utils/make-verification-token.js'\nimport { saveVerificationToken } from '../controllers/utils/save-verification-token.js'\nimport { User, UserStatus } from '../service/user/user.js'\nimport { VerificationTokenType } from '../service/verification-token/verification-token.js'\nimport { clearAccessTokenCookie, getAccessTokenCookie, setAccessTokenCookie } from '../utils/access-token-cookie.js'\nimport { SECRET } from '../utils/get-secret.js'\n\nconst sessionExpiryPolicy = config.get('session/expiryPolicy', 'fixed')\n\npassport.use(\n new JWTstrategy(\n {\n secretOrKey: SECRET,\n passReqToCallback: true,\n jwtFromRequest: ExtractJwt.fromExtractors([\n ExtractJwt.fromAuthHeaderAsBearerToken(),\n ExtractJwt.fromHeader('authorization'),\n ExtractJwt.fromHeader('x-access-token'),\n ExtractJwt.fromUrlQueryParameter('access_token'),\n ExtractJwt.fromBodyField('access_token'),\n req => {\n var token = null\n token = getAccessTokenCookie(req?.ctx)\n return token\n }\n ])\n },\n async (request, decoded, done) => {\n try {\n return done(null, decoded)\n } catch (error) {\n return done(error)\n }\n }\n )\n)\n\nexport async function jwtAuthenticateMiddleware(context, next) {\n const { path } = context\n const { user } = context.state\n if (user) {\n return await next()\n }\n\n return await passport.authenticate('jwt', { session: false }, async (err, decoded, info) => {\n if (err || !decoded) {\n const e = (context.state.error = err || info)\n\n clearAccessTokenCookie(context)\n\n context.throw(401, e.message)\n } else {\n const userEntity = await User.checkAuth(decoded)\n\n if (userEntity.status === UserStatus.PWD_RESET_REQUIRED) {\n try {\n const token = makeVerificationToken()\n await saveVerificationToken(userEntity.id, token, VerificationTokenType.PASSWORD_RESET)\n clearAccessTokenCookie(context)\n context.redirect(`/auth/reset-password?token=${token}`)\n } catch (e) {\n throw err\n }\n } else {\n context.state.user = userEntity\n context.state.decodedToken = decoded\n\n if (sessionExpiryPolicy == 'rolling') {\n /* To renew the expiry time on each request, a token is issued and the session is updated. */\n\n const token = await userEntity.sign()\n setAccessTokenCookie(context, token)\n }\n\n await next()\n }\n }\n })(context, next)\n}\n"]}
|
@@ -12,7 +12,11 @@ const ADMIN_ACCOUNT = env_1.config.get('adminAccount', {
|
|
12
12
|
password: 'admin'
|
13
13
|
});
|
14
14
|
const SEED_USERS = [
|
15
|
-
|
15
|
+
{
|
16
|
+
...ADMIN_ACCOUNT,
|
17
|
+
userType: 'user',
|
18
|
+
status: user_js_1.UserStatus.ACTIVATED
|
19
|
+
}
|
16
20
|
];
|
17
21
|
class SeedUsers1548206416130 {
|
18
22
|
async up(queryRunner) {
|
@@ -24,8 +28,12 @@ class SeedUsers1548206416130 {
|
|
24
28
|
const user = SEED_USERS[i];
|
25
29
|
const salt = user_js_1.User.generateSalt();
|
26
30
|
const password = user_js_1.User.encode(user.password, salt);
|
27
|
-
await userRepository.save(
|
28
|
-
|
31
|
+
await userRepository.save({
|
32
|
+
...user,
|
33
|
+
salt,
|
34
|
+
password,
|
35
|
+
domains: [domain]
|
36
|
+
});
|
29
37
|
}
|
30
38
|
}
|
31
39
|
catch (e) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"1548206416130-SeedUser.js","sourceRoot":"","sources":["../../server/migrations/1548206416130-SeedUser.ts"],"names":[],"mappings":";;;AAAA,qCAAgE;AAEhE,6CAAoD;AACpD,iDAA6D;AAE7D,qDAA0D;AAE1D,MAAM,aAAa,GAAG,YAAM,CAAC,GAAG,CAAC,cAAc,EAAE;IAC/C,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,oBAAoB;IAC3B,QAAQ,EAAE,OAAO;CAClB,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG;
|
1
|
+
{"version":3,"file":"1548206416130-SeedUser.js","sourceRoot":"","sources":["../../server/migrations/1548206416130-SeedUser.ts"],"names":[],"mappings":";;;AAAA,qCAAgE;AAEhE,6CAAoD;AACpD,iDAA6D;AAE7D,qDAA0D;AAE1D,MAAM,aAAa,GAAG,YAAM,CAAC,GAAG,CAAC,cAAc,EAAE;IAC/C,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,oBAAoB;IAC3B,QAAQ,EAAE,OAAO;CAClB,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG;IACjB;QACE,GAAG,aAAa;QAChB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,oBAAU,CAAC,SAAS;KAC7B;CACF,CAAA;AACD,MAAa,sBAAsB;IAC1B,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,cAAc,GAAG,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAA;QAC1C,MAAM,gBAAgB,GAAG,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAA;QAE9C,MAAM,MAAM,GAAW,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;QAEpF,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;gBAC1B,MAAM,IAAI,GAAG,cAAI,CAAC,YAAY,EAAE,CAAA;gBAChC,MAAM,QAAQ,GAAG,cAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;gBAEjD,MAAM,cAAc,CAAC,IAAI,CAAC;oBACxB,GAAG,IAAI;oBACP,IAAI;oBACJ,QAAQ;oBACR,OAAO,EAAE,CAAC,MAAM,CAAC;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,YAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAA,eAAK,EAAC,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;QAC5F,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,EAAE,CAAA;QAEvB,MAAM,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAA;QAEtC,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;YACxC,IAAI,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAA,eAAK,EAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACrE,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAtCD,wDAsCC","sourcesContent":["import { ILike, MigrationInterface, QueryRunner } from 'typeorm'\n\nimport { config, logger } from '@things-factory/env'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { User, UserStatus } from '../service/user/user.js'\n\nconst ADMIN_ACCOUNT = config.get('adminAccount', {\n username: 'admin',\n name: 'Admin',\n email: 'admin@hatiolab.com',\n password: 'admin'\n})\n\nconst SEED_USERS = [\n {\n ...ADMIN_ACCOUNT,\n userType: 'user',\n status: UserStatus.ACTIVATED\n }\n]\nexport class SeedUsers1548206416130 implements MigrationInterface {\n public async up(queryRunner: QueryRunner): Promise<any> {\n const userRepository = getRepository(User)\n const domainRepository = getRepository(Domain)\n\n const domain: Domain = await domainRepository.findOne({ where: { name: 'SYSTEM' } })\n\n try {\n for (let i = 0; i < SEED_USERS.length; i++) {\n const user = SEED_USERS[i]\n const salt = User.generateSalt()\n const password = User.encode(user.password, salt)\n\n await userRepository.save({\n ...user,\n salt,\n password,\n domains: [domain]\n })\n }\n } catch (e) {\n logger.error(e)\n }\n\n const admin = await userRepository.findOne({ where: { email: ILike(ADMIN_ACCOUNT.email) } })\n domain.owner = admin.id\n\n await domainRepository.save(domain)\n }\n\n public async down(queryRunner: QueryRunner): Promise<any> {\n const repository = getRepository(User)\n\n SEED_USERS.reverse().forEach(async user => {\n let record = await repository.findOneBy({ email: ILike(user.email) })\n await repository.remove(record)\n })\n }\n}\n"]}
|
@@ -46,8 +46,11 @@ if (!disableUserSignupProcess) {
|
|
46
46
|
const { domain } = context.state;
|
47
47
|
const user = context.request.body;
|
48
48
|
// try {
|
49
|
-
const { token } = await (0, signup_js_1.signup)(
|
50
|
-
|
49
|
+
const { token } = await (0, signup_js_1.signup)({
|
50
|
+
...user,
|
51
|
+
context,
|
52
|
+
domain
|
53
|
+
}, true);
|
51
54
|
const message = t('text.user registered successfully');
|
52
55
|
context.body = {
|
53
56
|
message,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"auth-signup-router.js","sourceRoot":"","sources":["../../server/router/auth-signup-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,6CAA4C;AAE5C,wDAAiD;AACjD,oDAA6C;AAC7C,4EAAsE;AACtE,kGAAwF;AAExF,MAAM,wBAAwB,GAAG,YAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;AAC9E,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AACrD,MAAM,gBAAgB,GAAG,YAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAExD,MAAM,YAAY,GAAG,YAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI;IAC7C,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,KAAK;IAClB,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,KAAK;IACtB,oBAAoB,EAAE,CAAC;IACvB,oBAAoB,EAAE,EAAE;CACzB,CAAA;AAEY,QAAA,gBAAgB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAE5C,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAC9B,wBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC3D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEzC,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;YAChC,WAAW,EAAE,aAAa;YAC1B,aAAa,EAAE,iBAAiB;YAChC,IAAI,EAAE;gBACJ,QAAQ;gBACR,KAAK;gBACL,YAAY;gBACZ,wBAAwB;gBACxB,0BAA0B;gBAC1B,SAAS;gBACT,gBAAgB;aACjB;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,wBAAgB,CAAC,IAAI,CAAC,cAAc,EAAE,IAAA,yDAAwB,EAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC5G,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAA;QAEjC,QAAQ;QACR,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,kBAAM,
|
1
|
+
{"version":3,"file":"auth-signup-router.js","sourceRoot":"","sources":["../../server/router/auth-signup-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,6CAA4C;AAE5C,wDAAiD;AACjD,oDAA6C;AAC7C,4EAAsE;AACtE,kGAAwF;AAExF,MAAM,wBAAwB,GAAG,YAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;AAC9E,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AACrD,MAAM,gBAAgB,GAAG,YAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAExD,MAAM,YAAY,GAAG,YAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI;IAC7C,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,KAAK;IAClB,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,KAAK;IACtB,oBAAoB,EAAE,CAAC;IACvB,oBAAoB,EAAE,EAAE;CACzB,CAAA;AAEY,QAAA,gBAAgB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAE5C,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAC9B,wBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC3D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEzC,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;YAChC,WAAW,EAAE,aAAa;YAC1B,aAAa,EAAE,iBAAiB;YAChC,IAAI,EAAE;gBACJ,QAAQ;gBACR,KAAK;gBACL,YAAY;gBACZ,wBAAwB;gBACxB,0BAA0B;gBAC1B,SAAS;gBACT,gBAAgB;aACjB;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,wBAAgB,CAAC,IAAI,CAAC,cAAc,EAAE,IAAA,yDAAwB,EAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC5G,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAA;QAEjC,QAAQ;QACR,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,kBAAM,EAC5B;YACE,GAAG,IAAI;YACP,OAAO;YACP,MAAM;SACP,EACD,IAAI,CACL,CAAA;QAED,MAAM,OAAO,GAAG,CAAC,CAAC,mCAAmC,CAAC,CAAA;QACtD,OAAO,CAAC,IAAI,GAAG;YACb,OAAO;YACP,KAAK;SACN,CAAA;QAED,IAAA,6CAAoB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QAEpC,IAAI,IAAA,oBAAO,EAAC,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YACjD,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;gBAChC,WAAW,EAAE,aAAa;gBAC1B,aAAa,EAAE,iBAAiB;gBAChC,IAAI,EAAE;oBACJ,OAAO;oBACP,wBAAwB;oBACxB,0BAA0B;oBAC1B,SAAS;iBACV;aACF,CAAC,CAAA;QACJ,CAAC;QACD,gBAAgB;QAChB,yBAAyB;QACzB,6BAA6B;QAE7B,wDAAwD;QACxD,0CAA0C;QAC1C,oCAAoC;QACpC,0CAA0C;QAC1C,gBAAgB;QAChB,iFAAiF;QACjF,uBAAuB;QACvB,UAAU;QACV,SAAS;QACT,MAAM;QACN,IAAI;IACN,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import Router from 'koa-router'\n\nimport { config } from '@things-factory/env'\n\nimport { signup } from '../controllers/signup.js'\nimport { accepts } from '../utils/accepts.js'\nimport { setAccessTokenCookie } from '../utils/access-token-cookie.js'\nimport { verifyRecaptcaMiddleware } from '../middlewares/verify-recaptcha-middleware.js'\n\nconst disableUserSignupProcess = config.get('disableUserSignupProcess', false)\nconst disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)\nconst languages = config.get('i18n/languages', false)\nconst recaptchaSiteKey = config.get('recaptcha/siteKey')\n\nconst passwordRule = config.get('password') || {\n lowerCase: true,\n upperCase: true,\n digit: true,\n specialCharacter: true,\n allowRepeat: false,\n useTightPattern: true,\n useLoosePattern: false,\n tightCharacterLength: 8,\n looseCharacterLength: 15\n}\n\nexport const authSignupRouter = new Router()\n\nif (!disableUserSignupProcess) {\n authSignupRouter.get('/auth/signup', async (context, next) => {\n const { username, email } = context.query\n\n await context.render('auth-page', {\n pageElement: 'auth-signup',\n elementScript: '/auth/signup.js',\n data: {\n username,\n email,\n passwordRule,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages,\n recaptchaSiteKey\n }\n })\n })\n\n authSignupRouter.post('/auth/signup', verifyRecaptcaMiddleware({ action: 'signup' }), async (context, next) => {\n const { header, t } = context\n const { domain } = context.state\n const user = context.request.body\n\n // try {\n const { token } = await signup(\n {\n ...user,\n context,\n domain\n },\n true\n )\n\n const message = t('text.user registered successfully')\n context.body = {\n message,\n token\n }\n\n setAccessTokenCookie(context, token)\n\n if (accepts(header.accept, ['text/html', '*/*'])) {\n await context.render('auth-page', {\n pageElement: 'auth-result',\n elementScript: '/auth/result.js',\n data: {\n message,\n disableUserSignupProcess,\n disableUserFavoredLanguage,\n languages\n }\n })\n }\n // } catch (e) {\n // context.status = 401\n // context.body = e.message\n\n // if (accepts(header.accept, ['text/html', '*/*'])) {\n // await context.render('auth-page', {\n // pageElement: 'auth-signup',\n // elementScript: '/auth/signup.js',\n // data: {\n // message: e instanceof AuthError ? t(`error.${e.message}`) : e.message,\n // passwordRule\n // }\n // })\n // }\n // }\n })\n}\n"]}
|
@@ -48,11 +48,14 @@ exports.oauth2AuthorizeRouter.get('/authorize', oauth2_server_js_1.server.author
|
|
48
48
|
elementScript,
|
49
49
|
data: {
|
50
50
|
domain,
|
51
|
-
oauth2:
|
51
|
+
oauth2: {
|
52
|
+
...oauth2,
|
53
|
+
user: {
|
52
54
|
id: oauth2.user.id,
|
53
55
|
name: oauth2.user.name,
|
54
56
|
email: oauth2.user.email
|
55
|
-
}
|
57
|
+
}
|
58
|
+
},
|
56
59
|
disableUserFavoredLanguage,
|
57
60
|
languages
|
58
61
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"oauth2-authorize-router.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-authorize-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,iDAAqD;AACrD,6CAA4C;AAE5C,6EAAsE;AACtE,yDAA2E;AAE9D,QAAA,qBAAqB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAEjD,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AAErD,8BAA8B;AAC9B,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAC9E,uEAAuE;AACvE,oEAAoE;AACpE,6EAA6E;AAC7E,8EAA8E;AAC9E,0DAA0D;AAC1D,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,iFAAiF;AACjF,0CAA0C;AAE1C,6BAAqB,CAAC,GAAG,CACvB,YAAY,EACZ,yBAAiB,CAAC,SAAS,CAAC,KAAK,WAAW,QAAQ,EAAE,WAAW;IAC/D,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,4BAAW,CAAC,CAAC,SAAS,CAAC;QACxD,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;IACF,oCAAoC;IACpC,4CAA4C;IAC5C,iBAAiB;IACjB,IAAI;IAEJ,OAAO,CAAC,MAAM,IAAI,4BAAS,EAAE,WAAW,CAAC,CAAA;AAC3C,CAAC,CAAC,EACF,KAAK,WAAW,OAAO,EAAE,IAAI;IAC3B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAE9C,IAAI,WAAW,GAAW,iBAAiB,CAAA;IAC3C,IAAI,aAAa,GAAW,iCAAiC,CAAA;IAE7D,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,4BAAS,CAAC,EAAE,EAAE,CAAC;QACtC,WAAW,GAAG,uBAAuB,CAAA;QACrC,aAAa,GAAG,uCAAuC,CAAA;IACzD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE;YAClC,WAAW;YACX,aAAa;YACb,IAAI,EAAE;gBACJ,MAAM;gBACN,MAAM,
|
1
|
+
{"version":3,"file":"oauth2-authorize-router.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-authorize-router.ts"],"names":[],"mappings":";;;;AAAA,oEAA+B;AAE/B,iDAAqD;AACrD,6CAA4C;AAE5C,6EAAsE;AACtE,yDAA2E;AAE9D,QAAA,qBAAqB,GAAG,IAAI,oBAAM,EAAE,CAAA;AAEjD,MAAM,0BAA0B,GAAG,YAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;AACvF,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAA;AAErD,8BAA8B;AAC9B,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAC9E,uEAAuE;AACvE,oEAAoE;AACpE,6EAA6E;AAC7E,8EAA8E;AAC9E,0DAA0D;AAC1D,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,iFAAiF;AACjF,0CAA0C;AAE1C,6BAAqB,CAAC,GAAG,CACvB,YAAY,EACZ,yBAAiB,CAAC,SAAS,CAAC,KAAK,WAAW,QAAQ,EAAE,WAAW;IAC/D,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,4BAAW,CAAC,CAAC,SAAS,CAAC;QACxD,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;IACF,oCAAoC;IACpC,4CAA4C;IAC5C,iBAAiB;IACjB,IAAI;IAEJ,OAAO,CAAC,MAAM,IAAI,4BAAS,EAAE,WAAW,CAAC,CAAA;AAC3C,CAAC,CAAC,EACF,KAAK,WAAW,OAAO,EAAE,IAAI;IAC3B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAE9C,IAAI,WAAW,GAAW,iBAAiB,CAAA;IAC3C,IAAI,aAAa,GAAW,iCAAiC,CAAA;IAE7D,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,4BAAS,CAAC,EAAE,EAAE,CAAC;QACtC,WAAW,GAAG,uBAAuB,CAAA;QACrC,aAAa,GAAG,uCAAuC,CAAA;IACzD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE;YAClC,WAAW;YACX,aAAa;YACb,IAAI,EAAE;gBACJ,MAAM;gBACN,MAAM,EAAE;oBACN,GAAG,MAAM;oBACT,IAAI,EAAE;wBACJ,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;wBAClB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;wBACtB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;qBACzB;iBACF;gBACD,0BAA0B;gBAC1B,SAAS;aACV;SACF,CAAC,CAAA;QACF,uCAAuC;QACvC,oBAAoB;QACpB,2HAA2H;QAC3H,oBAAoB;QACpB,KAAK;IACP,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,CAAA;IACT,CAAC;AACH,CAAC,CACF,CAAA","sourcesContent":["import Router from 'koa-router'\n\nimport { getRepository } from '@things-factory/shell'\nimport { config } from '@things-factory/env'\n\nimport { Application } from '../../service/application/application.js'\nimport { NonClient, server as oauth2orizeServer } from './oauth2-server.js'\n\nexport const oauth2AuthorizeRouter = new Router()\n\nconst disableUserFavoredLanguage = config.get('i18n/disableUserFavoredLanguage', false)\nconst languages = config.get('i18n/languages', false)\n\n// user authorization endpoint\n//\n// `authorization` middleware accepts a `validate` callback which is\n// responsible for validating the client making the authorization request. In\n// doing so, is recommended that the `redirectURI` be checked against a\n// registered value, although security requirements may vary accross\n// implementations. Once validated, the `done` callback must be invoked with\n// a `client` instance, as well as the `redirectURI` to which the user will be\n// redirected after an authorization decision is obtained.\n//\n// This middleware simply initializes a new authorization transaction. It is\n// the application's responsibility to authenticate the user and render a dialog\n// to obtain their approval (displaying details about the client requesting\n// authorization). We accomplish that here by routing through `ensureLoggedIn()`\n// first, and rendering the `dialog` view.\n\noauth2AuthorizeRouter.get(\n '/authorize',\n oauth2orizeServer.authorize(async function (clientID, redirectURI) {\n const client = await getRepository(Application).findOneBy({\n appKey: clientID\n })\n // CONFIRM-ME redirectUrl 의 허용 범위는 ?\n // if (!client.redirectUrl != redirectURI) {\n // return false\n // }\n\n return [client || NonClient, redirectURI]\n }),\n async function (context, next) {\n const { oauth2, user, domain } = context.state\n\n let pageElement: string = 'oauth2-decision'\n let elementScript: string = '/oauth2/oauth2-decision-page.js'\n\n if (oauth2.client.id === NonClient.id) {\n pageElement = 'oauth2-decision-error'\n elementScript = '/oauth2/oauth2-decision-error-page.js'\n }\n\n try {\n await context.render('oauth2-page', {\n pageElement,\n elementScript,\n data: {\n domain,\n oauth2: {\n ...oauth2,\n user: {\n id: oauth2.user.id,\n name: oauth2.user.name,\n email: oauth2.user.email\n }\n },\n disableUserFavoredLanguage,\n languages\n }\n })\n // await context.render(decisionPage, {\n // domain: domain,\n // ...oauth2, // client, redirectURI, req { type, clientID, redirectURI, scope, state}, user, transactionID, info, locals\n // availableScopes\n // })\n } catch (e) {\n throw e\n }\n }\n)\n"]}
|
@@ -47,8 +47,7 @@ exports.oauth2Router.post('/decision', index_js_1.jwtAuthenticateMiddleware, (0,
|
|
47
47
|
// authenticate when making requests to this endpoint.
|
48
48
|
exports.oauth2Router.post('/access-token', koa_passport_1.default.authenticate('oauth2-client-password', { session: false }), oauth2_server_js_1.server.token(), oauth2_server_js_1.server.errorHandler());
|
49
49
|
exports.oauth2Router.post('/refresh-token', async (context, next) => {
|
50
|
-
|
51
|
-
const refreshToken = (_b = (_a = context.request) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.refreshToken;
|
50
|
+
const refreshToken = context.request?.body?.refreshToken;
|
52
51
|
if (!refreshToken)
|
53
52
|
throw new Error('Missing refresh token');
|
54
53
|
const appUser = await (0, shell_1.getRepository)(user_js_1.User).findOneBy({
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"oauth2-router.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-router.ts"],"names":[],"mappings":";;;;AAAA,wEAA8B;AAC9B,sEAAiC;AACjC,wEAAmC;AACnC,oEAA+B;AAE/B,iDAA6D;AAE7D,yDAAsE;AACtE,6EAAsE;AACtE,wDAA6D;AAC7D,+EAAyE;AACzE,6DAAkD;AAClD,yDAAgE;AAChE,6FAAyF;AAU5E,QAAA,YAAY,GAAG,IAAI,oBAAM,EAAE,CAAA;AAExC,sBAAQ,CAAC,GAAG,CACV,wBAAwB,EACxB,IAAI,6CAAsB,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;IAC9D,IAAA,qBAAa,EAAC,4BAAW,CAAC;SACvB,SAAS,CAAC;QACT,MAAM,EAAE,QAAQ;KACjB,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,EAAE;QACb,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,IAAI,YAAY,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACjB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACpB,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAC5B,CAAC,CAAC,CACH,CAAA;AAED,yBAAyB;AACzB,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,cAAc;AAEd,oBAAY,CAAC,IAAI,CACf,WAAW,EACX,oCAAyB,EACzB,IAAA,qBAAO,EACL,yBAAiB,CAAC,QAAQ,CAAC,KAAK,WAAW,OAAO;IAChD,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;IAE3B,OAAO,OAAO,CAAC,IAAI,CAAA;AACrB,CAAC,CAAC,CACH,CACF,CAAA;AAED,iBAAiB;AACjB,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAC3E,sDAAsD;AAEtD,oBAAY,CAAC,IAAI,CACf,eAAe,EACf,sBAAQ,CAAC,YAAY,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EACnE,yBAAiB,CAAC,KAAK,EAAE,EACzB,yBAAiB,CAAC,YAAY,EAAE,CACjC,CAAA;AAED,oBAAY,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE
|
1
|
+
{"version":3,"file":"oauth2-router.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-router.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt from 'jsonwebtoken'\nimport compose from 'koa-compose'\nimport passport from 'koa-passport'\nimport Router from 'koa-router'\n\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { jwtAuthenticateMiddleware } from '../../middlewares/index.js'\nimport { Application } from '../../service/application/application.js'\nimport { User, UserStatus } from '../../service/user/user.js'\nimport { setAccessTokenCookie } from '../../utils/access-token-cookie.js'\nimport { SECRET } from '../../utils/get-secret.js'\nimport { server as oauth2orizeServer } from './oauth2-server.js'\nimport { Strategy as ClientPasswordStrategy } from './passport-oauth2-client-password.js'\n\ndeclare global {\n namespace NodeJS {\n interface Process {\n oauthDisconnect: (user: User) => Promise<void>\n }\n }\n}\n\nexport const oauth2Router = new Router()\n\npassport.use(\n 'oauth2-client-password',\n new ClientPasswordStrategy({}, (clientId, clientSecret, done) => {\n getRepository(Application)\n .findOneBy({\n appKey: clientId\n })\n .then(client => {\n if (!client || client.appSecret != clientSecret) {\n done(null, false)\n return\n }\n\n done(null, client)\n })\n .catch(err => done(err))\n })\n)\n\n// user decision endpoint\n//\n// `decision` middleware processes a user's decision to allow or deny access\n// requested by a client application. Based on the grant type requested by the\n// client, the above grant middleware configured above will be invoked to send\n// a response.\n\noauth2Router.post(\n '/decision',\n jwtAuthenticateMiddleware,\n compose(\n oauth2orizeServer.decision(async function (context) {\n const { request } = context\n\n return request.body\n })\n )\n)\n\n// token endpoint\n//\n// `token` middleware handles client requests to exchange authorization grants\n// for access tokens. Based on the grant type being exchanged, the above\n// exchange middleware will be invoked to handle the request. Clients must\n// authenticate when making requests to this endpoint.\n\noauth2Router.post(\n '/access-token',\n passport.authenticate('oauth2-client-password', { session: false }),\n oauth2orizeServer.token(),\n oauth2orizeServer.errorHandler()\n)\n\noauth2Router.post('/refresh-token', async (context, next) => {\n const refreshToken: string | undefined = context.request?.body?.refreshToken\n if (!refreshToken) throw new Error('Missing refresh token')\n\n const appUser: User | undefined = await getRepository(User).findOneBy({\n password: refreshToken\n })\n\n if (!appUser) throw new Error('App user is not found')\n\n try {\n jwt.verify(refreshToken, SECRET)\n const decoded = jwt.decode(refreshToken) as any\n const subdomain: string = decoded.domain.subdomain\n const domain: Domain | undefined = await getRepository(Domain).findOne({\n where: { subdomain }\n })\n if (!domain) throw new Error('Domain is not found')\n const appKey: string = decoded.application.appKey\n const scopes: any[] = decoded.scope\n\n const newAccessToken: string = Application.generateAccessToken(domain, appUser, appKey, scopes)\n const newRefreshToken: string = Application.generateRefreshToken(domain, appUser, appKey, scopes)\n\n appUser.password = newRefreshToken\n await getRepository(User).save(appUser)\n\n setAccessTokenCookie(context, newAccessToken)\n\n context.body = {\n accessToken: newAccessToken,\n refreshToken: newRefreshToken\n }\n } catch (e) {\n context.status = 401\n context.body = e.message\n }\n})\n\noauth2Router.get('/profile', jwtAuthenticateMiddleware, async (context, next) => {\n const { user, domain } = context.state\n\n const { name, description, email, userType: type, locale } = user\n const { name: domainName, subdomain, brandName, brandImage, contentImage, timezone } = domain || {}\n\n var application = {}\n if (type == 'application') {\n /* user entity에 reference 필드가 추가되기 전까지, appKey취득 방법임. */\n application['appKey'] = email.substr(0, email.lastIndexOf('@'))\n }\n\n context.body = {\n profile: {\n name,\n description,\n email,\n type /* (admin|user|application|appliance) */,\n domain: {\n name: domainName,\n subdomain,\n brandName,\n brandImage,\n contentImage,\n timezone\n },\n application\n }\n }\n})\n\noauth2Router.post('/disconnect', jwtAuthenticateMiddleware, async (context, next) => {\n try {\n let { user } = context.state\n\n if (typeof process.oauthDisconnect === 'function') {\n await process.oauthDisconnect(user)\n } else {\n user.domains = []\n user.roles = []\n user.status = UserStatus.DELETED\n await getRepository(User).save(user)\n }\n context.status = 200\n context.body = 'ok'\n } catch (e) {\n throw e\n }\n})\n"]}
|
@@ -99,7 +99,18 @@ exports.server.exchange(oauth2orize_koa_1.default.exchange.code(async (client, c
|
|
99
99
|
},
|
100
100
|
relations: ['domains', 'creator', 'updater']
|
101
101
|
});
|
102
|
-
appuser = await (0, shell_1.getRepository)(user_js_1.User).save(
|
102
|
+
appuser = await (0, shell_1.getRepository)(user_js_1.User).save({
|
103
|
+
...(appuser || {}),
|
104
|
+
email: appuserEmail,
|
105
|
+
name: application.name,
|
106
|
+
userType: 'application',
|
107
|
+
reference: application.id,
|
108
|
+
domains: [domain],
|
109
|
+
roles: scopes,
|
110
|
+
status: user_js_1.UserStatus.ACTIVATED,
|
111
|
+
updater: creator,
|
112
|
+
creator
|
113
|
+
});
|
103
114
|
// appuser = await getRepository(User).findOne({
|
104
115
|
// where: { email: ILike(appuserEmail) },
|
105
116
|
// relations: ['domains']
|
@@ -110,7 +121,10 @@ exports.server.exchange(oauth2orize_koa_1.default.exchange.code(async (client, c
|
|
110
121
|
// Lazy relation 업데이트 방법의 일관성이 부족하므로, Lazy relation 필드를 사용하지 않기를 권장함.
|
111
122
|
var accessToken = application_js_1.Application.generateAccessToken(domain, appuser, appKey, scopes);
|
112
123
|
var refreshToken = application_js_1.Application.generateRefreshToken(domain, appuser, appKey, scopes);
|
113
|
-
await (0, shell_1.getRepository)(user_js_1.User).save(
|
124
|
+
await (0, shell_1.getRepository)(user_js_1.User).save({
|
125
|
+
...appuser,
|
126
|
+
password: refreshToken
|
127
|
+
});
|
114
128
|
return [
|
115
129
|
accessToken,
|
116
130
|
refreshToken,
|
@@ -179,7 +193,11 @@ exports.server.exchange(oauth2orize_koa_1.default.exchange.refreshToken(async (c
|
|
179
193
|
});
|
180
194
|
var accessToken = application_js_1.Application.generateAccessToken(domain, appuser, appKey, scope);
|
181
195
|
var refreshToken = application_js_1.Application.generateRefreshToken(domain, appuser, appKey, scope);
|
182
|
-
await (0, shell_1.getRepository)(user_js_1.User).save(
|
196
|
+
await (0, shell_1.getRepository)(user_js_1.User).save({
|
197
|
+
...appuser,
|
198
|
+
roles,
|
199
|
+
password: refreshToken
|
200
|
+
});
|
183
201
|
return [
|
184
202
|
accessToken,
|
185
203
|
refreshToken,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"oauth2-server.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-server.ts"],"names":[],"mappings":"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","sourcesContent":["import oauth2orize from 'oauth2orize-koa'\nimport { ILike, In } from 'typeorm'\n\nimport { logger } from '@things-factory/env'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { Application } from '../../service/application/application.js'\nimport { Role } from '../../service/role/role.js'\nimport { User, UserStatus } from '../../service/user/user.js'\n\nconst crypto = require('crypto')\n\nexport const NOTFOUND = 'NOTFOUND'\nexport const NonClient = {\n id: NOTFOUND\n}\n\n// create OAuth 2.0 server\nexport const server = oauth2orize.createServer()\n\n// Register serialialization and deserialization functions.\n//\n// When a client redirects a user to user authorization endpoint, an\n// authorization transaction is initiated. To complete the transaction, the\n// user must authenticate and approve the authorization request. Because this\n// may involve multiple HTTP request/response exchanges, the transaction is\n// stored in the session.\n//\n// An application must supply serialization functions, which determine how the\n// client object is serialized into the session. Typically this will be a\n// simple matter of serializing the client's ID, and deserializing by finding\n// the client by ID from the database.\n\nserver.serializeClient(async function (client) {\n return client.id\n})\n\nserver.deserializeClient(async function (id) {\n if (id == NOTFOUND) {\n return {}\n }\n\n const application = await getRepository(Application).findOneBy({ id })\n return application\n})\n\n// Register supported grant types.\n//\n// OAuth 2.0 specifies a framework that allows users to grant client\n// applications limited access to their protected resources. It does this\n// through a process of the user granting access, and the client exchanging\n// the grant for an access token.\n\n// Grant authorization codes. The callback takes the `client` requesting\n// authorization, the `redirectURI` (which is used as a verifier in the\n// subsequent exchange), the authenticated `user` granting access, and\n// their response, which contains approved scope, duration, etc. as parsed by\n// the application. The application issues a code, which is bound to these\n// values, and will be exchanged for an access token.\n\nserver.grant(\n oauth2orize.grant.code(async (client, redirectUrl, user, ares, areq) => {\n const { email, appKey, subdomain, scopes, state } = ares\n\n return Application.generateAuthCode(email, appKey, subdomain, scopes, state)\n })\n)\n\n// Exchange authorization codes for access tokens. The callback accepts the\n// `client`, which is exchanging `code` and any `redirectURI` from the\n// authorization request for verification. If these values are validated, the\n// application issues an access token on behalf of the user who authorized the\n// code.\n\nserver.exchange(\n oauth2orize.exchange.code(async (client, code, redirectUrl) => {\n try {\n /* authorization code */\n var decoded: any = Application.verifyAuthCode(code)\n } catch (e) {\n return false\n }\n let { email, appKey, subdomain, scopes } = decoded\n\n const application: Application = await getRepository(Application).findOneBy({\n appKey\n })\n\n if (!application) {\n return false\n }\n\n /* DONT-FORGET uncomment after test */\n // if (redirectUrl !== application.redirectUrl && redirectUrl.indexOf(application.redirectUrl) != 0) {\n // logger.error(\n // 'oauth2 exchange error - redirectUrl should begins with the application setting',\n // redirectUrl,\n // application.redirectUrl\n // )\n // // return false\n // throw new TypeError(\n // `oauth2 exchange error - redirectUrl should begins with the application setting : '${redirectUrl}':'${application.redirectUrl}'`\n // )\n // }\n\n const domain: Domain = await getRepository(Domain).findOneBy({\n subdomain\n })\n\n const creator: User = await getRepository(User).findOneBy({ email: ILike(email) })\n\n const appuserEmail = `${crypto.randomUUID()}@${subdomain}`\n\n var appuser: User = await getRepository(User).findOne({\n where: {\n email: appuserEmail,\n reference: application.id,\n userType: 'application'\n },\n\n relations: ['domains', 'creator', 'updater']\n })\n\n appuser = await getRepository(User).save({\n ...(appuser || {}),\n email: appuserEmail,\n name: application.name,\n userType: 'application',\n reference: application.id,\n domains: [domain],\n roles: scopes,\n status: UserStatus.ACTIVATED,\n updater: creator,\n creator\n })\n\n // appuser = await getRepository(User).findOne({\n // where: { email: ILike(appuserEmail) },\n // relations: ['domains']\n // })\n\n // appuser.domains = Promise.resolve([domain])\n // await getRepository(User).save(appuser)\n // Lazy relation 필드들(domain, domains)들에 대한 업데이트. 이상의 방법으로 업데이트 해야하는 것 같다.\n // Lazy relation 업데이트 방법의 일관성이 부족하므로, Lazy relation 필드를 사용하지 않기를 권장함.\n\n var accessToken = Application.generateAccessToken(domain, appuser, appKey, scopes)\n var refreshToken = Application.generateRefreshToken(domain, appuser, appKey, scopes)\n\n await getRepository(User).save({\n ...(appuser as any),\n password: refreshToken\n })\n\n return [\n accessToken,\n refreshToken,\n {\n expires_in: 30 * 24 * 60 * 60 /* 30d */,\n token_type: 'bearer',\n centerId: subdomain\n }\n ]\n })\n)\n\nserver.exchange(\n oauth2orize.exchange.refreshToken(async (client, refreshToken, scope) => {\n try {\n /* refresh token */\n var decoded: any = Application.verifyAuthCode(refreshToken)\n } catch (e) {\n logger.error(e)\n return false\n }\n const {\n id,\n userType,\n email,\n application: { appKey },\n domain: { subdomain },\n scope: originalScope,\n exp: expires_in\n } = decoded\n\n const application: Application = await getRepository(Application).findOneBy({\n appKey\n })\n\n if (!application) {\n logger.error('application is not exist')\n return false\n }\n\n if (Date.now() > expires_in * 1000) {\n logger.error('refresh token is expired')\n return false\n }\n\n const domain: Domain = await getRepository(Domain).findOneBy({\n subdomain\n })\n\n const creator: User = await getRepository(User).findOneBy({\n id,\n userType\n })\n\n const appuserEmail = `${appKey}@${subdomain}`\n\n var appuser: User = await getRepository(User).findOne({\n where: {\n email: appuserEmail,\n reference: application.id,\n userType: 'application'\n },\n relations: ['domain', 'creator', 'updater']\n })\n\n if (!appuser) {\n logger.error('application is not bound')\n return false\n }\n\n /*\n * `scope` is the scope of access requested by the client, which must not include any scope not originally granted.\n */\n\n scope = scope || originalScope\n\n const scopes: string[] = scope.split(',')\n const originalScopes = (originalScope || '').split(',')\n const additionalScope = scopes.find(scope => originalScopes.indexOf(scope) === -1)\n if (additionalScope) {\n logger.error(`additional scope(${additionalScope}) required`)\n return false\n }\n\n const roles = await getRepository(Role).findBy({\n name: In(scopes),\n domain: { id: domain.id }\n })\n\n var accessToken = Application.generateAccessToken(domain, appuser, appKey, scope)\n var refreshToken: any = Application.generateRefreshToken(domain, appuser, appKey, scope)\n\n await getRepository(User).save({\n ...(appuser as any),\n roles,\n password: refreshToken\n })\n\n return [\n accessToken,\n refreshToken,\n {\n expires_in: 30 * 24 * 60 * 60 /* 30d */,\n token_type: 'bearer'\n }\n ]\n })\n)\n"]}
|
1
|
+
{"version":3,"file":"oauth2-server.js","sourceRoot":"","sources":["../../../server/router/oauth2/oauth2-server.ts"],"names":[],"mappings":"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","sourcesContent":["import oauth2orize from 'oauth2orize-koa'\nimport { ILike, In } from 'typeorm'\n\nimport { logger } from '@things-factory/env'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { Application } from '../../service/application/application.js'\nimport { Role } from '../../service/role/role.js'\nimport { User, UserStatus } from '../../service/user/user.js'\n\nconst crypto = require('crypto')\n\nexport const NOTFOUND = 'NOTFOUND'\nexport const NonClient = {\n id: NOTFOUND\n}\n\n// create OAuth 2.0 server\nexport const server = oauth2orize.createServer()\n\n// Register serialialization and deserialization functions.\n//\n// When a client redirects a user to user authorization endpoint, an\n// authorization transaction is initiated. To complete the transaction, the\n// user must authenticate and approve the authorization request. Because this\n// may involve multiple HTTP request/response exchanges, the transaction is\n// stored in the session.\n//\n// An application must supply serialization functions, which determine how the\n// client object is serialized into the session. Typically this will be a\n// simple matter of serializing the client's ID, and deserializing by finding\n// the client by ID from the database.\n\nserver.serializeClient(async function (client) {\n return client.id\n})\n\nserver.deserializeClient(async function (id) {\n if (id == NOTFOUND) {\n return {}\n }\n\n const application = await getRepository(Application).findOneBy({ id })\n return application\n})\n\n// Register supported grant types.\n//\n// OAuth 2.0 specifies a framework that allows users to grant client\n// applications limited access to their protected resources. It does this\n// through a process of the user granting access, and the client exchanging\n// the grant for an access token.\n\n// Grant authorization codes. The callback takes the `client` requesting\n// authorization, the `redirectURI` (which is used as a verifier in the\n// subsequent exchange), the authenticated `user` granting access, and\n// their response, which contains approved scope, duration, etc. as parsed by\n// the application. The application issues a code, which is bound to these\n// values, and will be exchanged for an access token.\n\nserver.grant(\n oauth2orize.grant.code(async (client, redirectUrl, user, ares, areq) => {\n const { email, appKey, subdomain, scopes, state } = ares\n\n return Application.generateAuthCode(email, appKey, subdomain, scopes, state)\n })\n)\n\n// Exchange authorization codes for access tokens. The callback accepts the\n// `client`, which is exchanging `code` and any `redirectURI` from the\n// authorization request for verification. If these values are validated, the\n// application issues an access token on behalf of the user who authorized the\n// code.\n\nserver.exchange(\n oauth2orize.exchange.code(async (client, code, redirectUrl) => {\n try {\n /* authorization code */\n var decoded: any = Application.verifyAuthCode(code)\n } catch (e) {\n return false\n }\n let { email, appKey, subdomain, scopes } = decoded\n\n const application: Application = await getRepository(Application).findOneBy({\n appKey\n })\n\n if (!application) {\n return false\n }\n\n /* DONT-FORGET uncomment after test */\n // if (redirectUrl !== application.redirectUrl && redirectUrl.indexOf(application.redirectUrl) != 0) {\n // logger.error(\n // 'oauth2 exchange error - redirectUrl should begins with the application setting',\n // redirectUrl,\n // application.redirectUrl\n // )\n // // return false\n // throw new TypeError(\n // `oauth2 exchange error - redirectUrl should begins with the application setting : '${redirectUrl}':'${application.redirectUrl}'`\n // )\n // }\n\n const domain: Domain = await getRepository(Domain).findOneBy({\n subdomain\n })\n\n const creator: User = await getRepository(User).findOneBy({ email: ILike(email) })\n\n const appuserEmail = `${crypto.randomUUID()}@${subdomain}`\n\n var appuser: User = await getRepository(User).findOne({\n where: {\n email: appuserEmail,\n reference: application.id,\n userType: 'application'\n },\n\n relations: ['domains', 'creator', 'updater']\n })\n\n appuser = await getRepository(User).save({\n ...(appuser || {}),\n email: appuserEmail,\n name: application.name,\n userType: 'application',\n reference: application.id,\n domains: [domain],\n roles: scopes,\n status: UserStatus.ACTIVATED,\n updater: creator,\n creator\n })\n\n // appuser = await getRepository(User).findOne({\n // where: { email: ILike(appuserEmail) },\n // relations: ['domains']\n // })\n\n // appuser.domains = Promise.resolve([domain])\n // await getRepository(User).save(appuser)\n // Lazy relation 필드들(domain, domains)들에 대한 업데이트. 이상의 방법으로 업데이트 해야하는 것 같다.\n // Lazy relation 업데이트 방법의 일관성이 부족하므로, Lazy relation 필드를 사용하지 않기를 권장함.\n\n var accessToken = Application.generateAccessToken(domain, appuser, appKey, scopes)\n var refreshToken = Application.generateRefreshToken(domain, appuser, appKey, scopes)\n\n await getRepository(User).save({\n ...(appuser as any),\n password: refreshToken\n })\n\n return [\n accessToken,\n refreshToken,\n {\n expires_in: 30 * 24 * 60 * 60 /* 30d */,\n token_type: 'bearer',\n centerId: subdomain\n }\n ]\n })\n)\n\nserver.exchange(\n oauth2orize.exchange.refreshToken(async (client, refreshToken, scope) => {\n try {\n /* refresh token */\n var decoded: any = Application.verifyAuthCode(refreshToken)\n } catch (e) {\n logger.error(e)\n return false\n }\n const {\n id,\n userType,\n email,\n application: { appKey },\n domain: { subdomain },\n scope: originalScope,\n exp: expires_in\n } = decoded\n\n const application: Application = await getRepository(Application).findOneBy({\n appKey\n })\n\n if (!application) {\n logger.error('application is not exist')\n return false\n }\n\n if (Date.now() > expires_in * 1000) {\n logger.error('refresh token is expired')\n return false\n }\n\n const domain: Domain = await getRepository(Domain).findOneBy({\n subdomain\n })\n\n const creator: User = await getRepository(User).findOneBy({\n id,\n userType\n })\n\n const appuserEmail = `${appKey}@${subdomain}`\n\n var appuser: User = await getRepository(User).findOne({\n where: {\n email: appuserEmail,\n reference: application.id,\n userType: 'application'\n },\n relations: ['domain', 'creator', 'updater']\n })\n\n if (!appuser) {\n logger.error('application is not bound')\n return false\n }\n\n /*\n * `scope` is the scope of access requested by the client, which must not include any scope not originally granted.\n */\n\n scope = scope || originalScope\n\n const scopes: string[] = scope.split(',')\n const originalScopes = (originalScope || '').split(',')\n const additionalScope = scopes.find(scope => originalScopes.indexOf(scope) === -1)\n if (additionalScope) {\n logger.error(`additional scope(${additionalScope}) required`)\n return false\n }\n\n const roles = await getRepository(Role).findBy({\n name: In(scopes),\n domain: { id: domain.id }\n })\n\n var accessToken = Application.generateAccessToken(domain, appuser, appKey, scope)\n var refreshToken: any = Application.generateRefreshToken(domain, appuser, appKey, scope)\n\n await getRepository(User).save({\n ...(appuser as any),\n roles,\n password: refreshToken\n })\n\n return [\n accessToken,\n refreshToken,\n {\n expires_in: 30 * 24 * 60 * 60 /* 30d */,\n token_type: 'bearer'\n }\n ]\n })\n)\n"]}
|