@things-factory/auth-base 6.2.49 → 6.2.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/client/directive/privileged.ts +1 -1
  2. package/client/profiled.ts +22 -17
  3. package/dist-client/directive/privileged.d.ts +2 -2
  4. package/dist-client/directive/privileged.js.map +1 -1
  5. package/dist-client/profiled.d.ts +2 -3
  6. package/dist-client/profiled.js +18 -9
  7. package/dist-client/profiled.js.map +1 -1
  8. package/dist-client/tsconfig.tsbuildinfo +1 -1
  9. package/dist-server/constants/error-code.js.map +1 -1
  10. package/dist-server/index.d.ts +1 -0
  11. package/dist-server/index.js +1 -0
  12. package/dist-server/index.js.map +1 -1
  13. package/dist-server/router/auth-private-process-router.js +9 -3
  14. package/dist-server/router/auth-private-process-router.js.map +1 -1
  15. package/dist-server/service/domain-generator/domain-generator-mutation.js +1 -1
  16. package/dist-server/service/domain-generator/domain-generator-mutation.js.map +1 -1
  17. package/dist-server/service/partner/partner-mutation.js +1 -1
  18. package/dist-server/service/partner/partner-mutation.js.map +1 -1
  19. package/dist-server/service/privilege/privilege-directive.js +9 -12
  20. package/dist-server/service/privilege/privilege-directive.js.map +1 -1
  21. package/dist-server/service/privilege/privilege-query.d.ts +3 -3
  22. package/dist-server/service/privilege/privilege-query.js +23 -21
  23. package/dist-server/service/privilege/privilege-query.js.map +1 -1
  24. package/dist-server/service/privilege/privilege.d.ts +0 -2
  25. package/dist-server/service/privilege/privilege.js +0 -8
  26. package/dist-server/service/privilege/privilege.js.map +1 -1
  27. package/dist-server/service/user/user.d.ts +2 -2
  28. package/dist-server/service/user/user.js +5 -5
  29. package/dist-server/service/user/user.js.map +1 -1
  30. package/dist-server/tsconfig.tsbuildinfo +1 -1
  31. package/dist-server/utils/check-permission.d.ts +7 -0
  32. package/dist-server/utils/check-permission.js +38 -0
  33. package/dist-server/utils/check-permission.js.map +1 -0
  34. package/package.json +5 -5
  35. package/server/constants/error-code.ts +1 -1
  36. package/server/index.ts +2 -0
  37. package/server/router/auth-private-process-router.ts +11 -3
  38. package/server/service/domain-generator/domain-generator-mutation.ts +1 -1
  39. package/server/service/partner/partner-mutation.ts +1 -1
  40. package/server/service/privilege/privilege-directive.ts +21 -13
  41. package/server/service/privilege/privilege-query.ts +15 -13
  42. package/server/service/privilege/privilege.ts +0 -6
  43. package/server/service/user/user.ts +5 -5
  44. package/server/utils/check-permission.ts +52 -0
  45. package/translations/ms.json +53 -53
  46. package/translations/zh.json +35 -35
@@ -0,0 +1,7 @@
1
+ import { Domain } from '@things-factory/shell';
2
+ import { PrivilegeObject } from '../service/privilege/privilege';
3
+ import { User } from '../service/user/user';
4
+ export declare function checkPermission(privilegeObject: PrivilegeObject, user: User, domain: Domain, unsafeIP?: boolean, prohibitedPrivileges?: {
5
+ category: string;
6
+ privilege: string;
7
+ }[]): Promise<boolean>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkPermission = void 0;
4
+ const user_1 = require("../service/user/user");
5
+ async function checkPermission(privilegeObject, user, domain, unsafeIP, prohibitedPrivileges) {
6
+ if (!privilegeObject) {
7
+ return true;
8
+ }
9
+ const { owner: domainOwnerGranted, super: superUserGranted, category, privilege } = privilegeObject;
10
+ if (unsafeIP) {
11
+ if (privilege && category) {
12
+ // unsafeIP 상황에서는 ownership granted는 적용되지 않는다.
13
+ if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {
14
+ return false;
15
+ }
16
+ return await user_1.User.hasPrivilege(privilege, category, domain, user);
17
+ }
18
+ // privilege, category가 설정되지 않은 경우에는 ownership granted가 설정되었다면 허가하지 않는다.
19
+ return !domainOwnerGranted && !superUserGranted;
20
+ }
21
+ else {
22
+ if (!privilege || !category) {
23
+ // privilege, category가 설정되지 않은 경우에는 ownership granted만을 적용한다.
24
+ return ((domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||
25
+ (superUserGranted && (await process.superUserGranted(domain, user))));
26
+ }
27
+ if ((domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||
28
+ (superUserGranted && (await process.superUserGranted(domain, user)))) {
29
+ return true;
30
+ }
31
+ if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {
32
+ return false;
33
+ }
34
+ return await user_1.User.hasPrivilege(privilege, category, domain, user);
35
+ }
36
+ }
37
+ exports.checkPermission = checkPermission;
38
+ //# sourceMappingURL=check-permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-permission.js","sourceRoot":"","sources":["../../server/utils/check-permission.ts"],"names":[],"mappings":";;;AAEA,+CAA2C;AAEpC,KAAK,UAAU,eAAe,CACnC,eAAgC,EAChC,IAAU,EACV,MAAc,EACd,QAAkB,EAClB,oBAAgE;IAEhE,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,eAAe,CAAA;IAEnG,IAAI,QAAQ,EAAE;QACZ,IAAI,SAAS,IAAI,QAAQ,EAAE;YACzB,8CAA8C;YAC9C,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,QAAQ,IAAI,EAAE,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE;gBACjG,OAAO,KAAK,CAAA;aACb;YAED,OAAO,MAAM,WAAI,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;SAClE;QAED,wEAAwE;QACxE,OAAO,CAAC,kBAAkB,IAAI,CAAC,gBAAgB,CAAA;KAChD;SAAM;QACL,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE;YAC3B,8DAA8D;YAC9D,OAAO,CACL,CAAC,kBAAkB,IAAI,CAAC,MAAM,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;gBACxE,CAAC,gBAAgB,IAAI,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CACrE,CAAA;SACF;QAED,IACE,CAAC,kBAAkB,IAAI,CAAC,MAAM,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YACxE,CAAC,gBAAgB,IAAI,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EACpE;YACA,OAAO,IAAI,CAAA;SACZ;QAED,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,QAAQ,IAAI,EAAE,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE;YACjG,OAAO,KAAK,CAAA;SACb;QAED,OAAO,MAAM,WAAI,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;KAClE;AACH,CAAC;AA/CD,0CA+CC","sourcesContent":["import { Domain } from '@things-factory/shell'\nimport { PrivilegeObject } from '../service/privilege/privilege'\nimport { User } from '../service/user/user'\n\nexport async function checkPermission(\n privilegeObject: PrivilegeObject,\n user: User,\n domain: Domain,\n unsafeIP?: boolean,\n prohibitedPrivileges?: { category: string; privilege: string }[]\n): Promise<boolean> {\n if (!privilegeObject) {\n return true\n }\n\n const { owner: domainOwnerGranted, super: superUserGranted, category, privilege } = privilegeObject\n\n if (unsafeIP) {\n if (privilege && category) {\n // unsafeIP 상황에서는 ownership granted는 적용되지 않는다.\n if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {\n return false\n }\n\n return await User.hasPrivilege(privilege, category, domain, user)\n }\n\n // privilege, category가 설정되지 않은 경우에는 ownership granted가 설정되었다면 허가하지 않는다.\n return !domainOwnerGranted && !superUserGranted\n } else {\n if (!privilege || !category) {\n // privilege, category가 설정되지 않은 경우에는 ownership granted만을 적용한다.\n return (\n (domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||\n (superUserGranted && (await process.superUserGranted(domain, user)))\n )\n }\n\n if (\n (domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||\n (superUserGranted && (await process.superUserGranted(domain, user)))\n ) {\n return true\n }\n\n if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {\n return false\n }\n\n return await User.hasPrivilege(privilege, category, domain, user)\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/auth-base",
3
- "version": "6.2.49",
3
+ "version": "6.2.51",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -30,10 +30,10 @@
30
30
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
31
31
  },
32
32
  "dependencies": {
33
- "@things-factory/email-base": "^6.2.48",
33
+ "@things-factory/email-base": "^6.2.51",
34
34
  "@things-factory/env": "^6.2.33",
35
- "@things-factory/i18n-base": "^6.2.48",
36
- "@things-factory/shell": "^6.2.48",
35
+ "@things-factory/i18n-base": "^6.2.51",
36
+ "@things-factory/shell": "^6.2.51",
37
37
  "@things-factory/utils": "^6.2.48",
38
38
  "jsonwebtoken": "^9.0.0",
39
39
  "koa-passport": "^6.0.0",
@@ -43,5 +43,5 @@
43
43
  "passport-local": "^1.0.0",
44
44
  "popsicle-cookie-jar": "^1.0.0"
45
45
  },
46
- "gitHead": "57266c96220301729f9c5cd633af1a4e2a651096"
46
+ "gitHead": "365e8ae6475eede1a4fd51460c24569d13de14b6"
47
47
  }
@@ -14,4 +14,4 @@ export const CONFIRM_PASSWORD_NOT_MATCHED = 'confirm password not matched'
14
14
  export const PASSWORD_PATTERN_NOT_MATCHED = 'password should match the rule'
15
15
  export const USER_DUPLICATED = 'user duplicated'
16
16
  export const PASSWORD_USED_PAST = 'password used in the past'
17
- export const VERIFICATION_ERROR = 'user or verification token not found'
17
+ export const VERIFICATION_ERROR = 'user or verification token not found'
package/server/index.ts CHANGED
@@ -16,6 +16,8 @@ export * from './utils/get-secret'
16
16
  export * from './utils/check-user-belongs-domain'
17
17
  export * from './utils/access-token-cookie'
18
18
  export * from './utils/encrypt-state'
19
+ export * from './utils/check-permission'
20
+
19
21
  export * from './errors'
20
22
 
21
23
  export * from './types'
@@ -67,11 +67,19 @@ authPrivateProcessRouter
67
67
  clearAccessTokenCookie(context)
68
68
  })
69
69
  .get('/profile', async (context, next) => {
70
- const { domain, user, protected: protectedIP } = context.state
70
+ const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
71
71
 
72
72
  let domains: Partial<Domain>[] = await getUserDomains(user)
73
73
  domains = domains.filter((d: Domain) => d.extType == domainType)
74
74
 
75
+ var privileges = await User.getPrivilegesByDomain(user, domain)
76
+
77
+ if (prohibitedPrivileges) {
78
+ prohibitedPrivileges.forEach(({ category, name }) => {
79
+ privileges = privileges.filter(p => p.category != category || p.name != name)
80
+ })
81
+ }
82
+
75
83
  context.body = {
76
84
  user: {
77
85
  email: user.email,
@@ -79,8 +87,8 @@ authPrivateProcessRouter
79
87
  userType: user.userType,
80
88
  owner: await process.domainOwnerGranted(domain, user),
81
89
  super: await process.superUserGranted(domain, user),
82
- protected: protectedIP,
83
- privileges: await User.getPrivilegesByDomain(user, domain)
90
+ unsafeIP,
91
+ privileges
84
92
  },
85
93
  domains,
86
94
  domain: domain && {
@@ -11,7 +11,7 @@ import { DomainGeneratorInput, DomainUserRoleInput } from './domain-generator-ty
11
11
 
12
12
  @Resolver()
13
13
  export class DomainGeneratorMutation {
14
- @Directive('@privilege(category: "system", privilege: "mutation", superUserGranted: true)')
14
+ @Directive('@privilege(superUserGranted: true)')
15
15
  @Directive('@transaction')
16
16
  @Mutation(returns => Domain)
17
17
  async domainRegister(
@@ -46,7 +46,7 @@ export class PartnerMutation {
46
46
 
47
47
  // Find partner
48
48
  const partner: Partner = await tx.getRepository(Partner).findOne({
49
- where: { domain: { id: domain.id }, partnerDomain }
49
+ where: { domain: { id: domain.id }, partnerDomain: { id: partnerDomain.id } }
50
50
  })
51
51
  if (!partner) throw new Error(context.t('error.failed to find x', { x: context.t('label.partner') }))
52
52
 
@@ -3,6 +3,7 @@ import gql from 'graphql-tag'
3
3
 
4
4
  import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'
5
5
  import { User } from '../user/user'
6
+ import { checkPermission } from '../../utils/check-permission'
6
7
 
7
8
  process['PRIVILEGES'] = {}
8
9
 
@@ -33,22 +34,29 @@ export const privilegeDirectiveResolver = (schema: GraphQLSchema) =>
33
34
  }
34
35
 
35
36
  fieldConfig.resolve = async function (source, args, context, info) {
36
- const { domain, user } = context.state
37
+ const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
37
38
 
38
- if (domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) {
39
- return await resolve.call(this, source, args, context, info)
40
- }
41
-
42
- if (superUserGranted && (await process.superUserGranted(domain, user))) {
43
- return await resolve.call(this, source, args, context, info)
44
- }
45
-
46
- if (!category || !privilege) throw new Error(`Unauthorized! ${category}-${privilege} privilege required`)
47
-
48
- if (await User.hasPrivilege(privilege, category, domain, user)) {
39
+ if (
40
+ await checkPermission(
41
+ {
42
+ category,
43
+ privilege,
44
+ owner: domainOwnerGranted,
45
+ super: superUserGranted
46
+ },
47
+ user,
48
+ domain,
49
+ unsafeIP,
50
+ prohibitedPrivileges
51
+ )
52
+ ) {
49
53
  return await resolve.call(this, source, args, context, info)
50
54
  } else {
51
- throw new Error(`Unauthorized! ${category}-${privilege} privilege required`)
55
+ throw new Error(
56
+ `Unauthorized! ${
57
+ category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'
58
+ } required`
59
+ )
52
60
  }
53
61
  }
54
62
 
@@ -8,14 +8,6 @@ import { PrivilegeList } from './privilege-types'
8
8
 
9
9
  @Resolver(Privilege)
10
10
  export class PrivilegeQuery {
11
- @Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
12
- @Query(returns => Privilege, { description: 'To fetch privilege' })
13
- async privilege(@Arg('name') name: string, @Arg('category') category: string): Promise<Privilege> {
14
- return await getRepository(Privilege).findOne({
15
- where: { name, category }
16
- })
17
- }
18
-
19
11
  @Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
20
12
  @Query(returns => PrivilegeList, { description: 'To fetch multiple privileges' })
21
13
  async privileges(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<PrivilegeList> {
@@ -23,7 +15,12 @@ export class PrivilegeQuery {
23
15
  params,
24
16
  repository: getRepository(Privilege),
25
17
  alias: 'p',
26
- searchables: ['name', 'category']
18
+ searchables: ['privilege', 'category'],
19
+ filtersMap: {
20
+ privilege: {
21
+ columnName: 'name'
22
+ }
23
+ }
27
24
  })
28
25
  .orderBy('p.category', 'ASC')
29
26
  .getManyAndCount()
@@ -42,22 +39,22 @@ export class PrivilegeQuery {
42
39
 
43
40
  @Query(returns => Boolean, { description: 'To query whether I have the given permission' })
44
41
  async hasPrivilege(
45
- @Arg('name') name: string,
42
+ @Arg('privilege') privilege: string,
46
43
  @Arg('category') category: string,
47
44
  @Ctx() context: ResolverContext
48
45
  ): Promise<Boolean> {
49
46
  const { domain, user } = context.state
50
- return await User.hasPrivilege(name, category, domain, user)
47
+ return await User.hasPrivilege(privilege, category, domain, user)
51
48
  }
52
49
 
53
50
  @Query(returns => [Domain], { description: 'To fetch domains with given privilege for user' })
54
51
  async domainsWithPrivilege(
55
- @Arg('name') name: string,
52
+ @Arg('privilege') privilege: string,
56
53
  @Arg('category') category: string,
57
54
  @Ctx() context: ResolverContext
58
55
  ): Promise<Partial<Domain>[]> {
59
56
  const { user } = context.state
60
- return await User.getDomainsWithPrivilege(name, category, user)
57
+ return await User.getDomainsWithPrivilege(privilege, category, user)
61
58
  }
62
59
 
63
60
  @FieldResolver(type => String)
@@ -76,6 +73,11 @@ export class PrivilegeQuery {
76
73
  })
77
74
  }
78
75
 
76
+ @FieldResolver(type => String)
77
+ async privilege(@Root() privilege: Privilege, @Ctx() context: ResolverContext) {
78
+ return privilege.name
79
+ }
80
+
79
81
  @FieldResolver(type => [Role])
80
82
  async roles(@Root() privilege: Privilege) {
81
83
  return (
@@ -27,9 +27,6 @@ export class PrivilegeObject {
27
27
 
28
28
  @Field({ nullable: true })
29
29
  super?: boolean
30
-
31
- @Field({ nullable: true })
32
- protected?: boolean
33
30
  }
34
31
 
35
32
  @InputType()
@@ -45,9 +42,6 @@ export class PrivilegeInput {
45
42
 
46
43
  @Field({ nullable: true })
47
44
  super?: boolean
48
-
49
- @Field({ nullable: true })
50
- protected?: boolean
51
45
  }
52
46
 
53
47
  @Entity()
@@ -312,12 +312,12 @@ export class User {
312
312
  }
313
313
  }
314
314
 
315
- static async hasPrivilege(name: string, category: string, domain: Domain, user: User) {
315
+ static async hasPrivilege(privilege: string, category: string, domain: Domain, user: User) {
316
316
  const result = await getRepository(User).query(
317
317
  `
318
318
  SELECT COUNT(1) AS "has_privilege" FROM "privileges" "PRIVILEGES"
319
319
  WHERE "PRIVILEGES"."category" = '${category}'
320
- AND "PRIVILEGES"."name" = '${name}'
320
+ AND "PRIVILEGES"."name" = '${privilege}'
321
321
  AND "PRIVILEGES"."id" IN (
322
322
  SELECT "RP"."privileges_id"
323
323
  FROM "users_roles" "UR"
@@ -334,7 +334,7 @@ export class User {
334
334
 
335
335
  static async getPrivilegesByDomain(user: User, domain: Domain) {
336
336
  const result = await getRepository(User).query(`
337
- SELECT name, category FROM "privileges" "PRIVILEGES"
337
+ SELECT name privilege, category FROM "privileges" "PRIVILEGES"
338
338
  WHERE "PRIVILEGES"."id" IN (
339
339
  SELECT "RP"."privileges_id"
340
340
  FROM "users_roles" "UR"
@@ -347,7 +347,7 @@ export class User {
347
347
  return result
348
348
  }
349
349
 
350
- static async getDomainsWithPrivilege(name: string, category: string, user: User) {
351
- return getDomainsWithPrivilege(user, name, category)
350
+ static async getDomainsWithPrivilege(privilege: string, category: string, user: User) {
351
+ return getDomainsWithPrivilege(user, privilege, category)
352
352
  }
353
353
  }
@@ -0,0 +1,52 @@
1
+ import { Domain } from '@things-factory/shell'
2
+ import { PrivilegeObject } from '../service/privilege/privilege'
3
+ import { User } from '../service/user/user'
4
+
5
+ export async function checkPermission(
6
+ privilegeObject: PrivilegeObject,
7
+ user: User,
8
+ domain: Domain,
9
+ unsafeIP?: boolean,
10
+ prohibitedPrivileges?: { category: string; privilege: string }[]
11
+ ): Promise<boolean> {
12
+ if (!privilegeObject) {
13
+ return true
14
+ }
15
+
16
+ const { owner: domainOwnerGranted, super: superUserGranted, category, privilege } = privilegeObject
17
+
18
+ if (unsafeIP) {
19
+ if (privilege && category) {
20
+ // unsafeIP 상황에서는 ownership granted는 적용되지 않는다.
21
+ if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {
22
+ return false
23
+ }
24
+
25
+ return await User.hasPrivilege(privilege, category, domain, user)
26
+ }
27
+
28
+ // privilege, category가 설정되지 않은 경우에는 ownership granted가 설정되었다면 허가하지 않는다.
29
+ return !domainOwnerGranted && !superUserGranted
30
+ } else {
31
+ if (!privilege || !category) {
32
+ // privilege, category가 설정되지 않은 경우에는 ownership granted만을 적용한다.
33
+ return (
34
+ (domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||
35
+ (superUserGranted && (await process.superUserGranted(domain, user)))
36
+ )
37
+ }
38
+
39
+ if (
40
+ (domainOwnerGranted && (await process.domainOwnerGranted(domain, user))) ||
41
+ (superUserGranted && (await process.superUserGranted(domain, user)))
42
+ ) {
43
+ return true
44
+ }
45
+
46
+ if ((prohibitedPrivileges || []).find(pp => pp.category == category && pp.privilege == privilege)) {
47
+ return false
48
+ }
49
+
50
+ return await User.hasPrivilege(privilege, category, domain, user)
51
+ }
52
+ }
@@ -1,55 +1,55 @@
1
1
  {
2
- "field.email": "e-mel",
3
- "field.password": "kata-laluan",
4
- "field.token": "token",
5
- "field.appliance_id": "perkakas",
6
- "field.brand": "jenama",
7
- "field.model": "model",
8
- "field.active": "aktif",
9
- "field.category": "kategori",
10
- "field.roles": "peranan",
11
- "field.privileges": "keistimewaan",
12
- "field.user": "pengguna",
13
- "field.user_type": "[ms] user type",
14
- "field.user_account": "akaun pengguna",
15
- "label.partner": "[ms] partner",
16
- "text.account is reactivated": "[ms] account is reactivated",
17
- "text.delete account succeed": "[ms] delete account succeed",
18
- "text.inactive user": "[ms] inactive user",
19
- "text.invalid verification token": "[ms] invalid verification token",
20
- "text.invitation email sent": "[ms] invitation email sent",
21
- "text.pattern_minimum_charaters": "[ms] minimum {length} charaters",
22
- "text.pattern_atleast_1_lowercase": "[ms] at least 1 lowercase character",
23
- "text.pattern_atleast_1_uppercase": "[ms] at least 1 uppercase character",
24
- "text.pattern_atleast_1_digit": "[ms] at least 1 digit character",
25
- "text.pattern_atleast_1_special": "[ms] at least 1 special character(!@#$%^&*())",
26
- "text.pattern_not_allowed": "[ms] not allowed repeated charater",
27
- "text.password reset succeed": "[ms] password reset succeed",
28
- "text.password changed successfully": "[ms] password changed successfully",
29
- "text.profile changed successfully": "[ms] profile changed successfully",
30
- "text.result": "[ms] result",
31
- "text.signout successfully": "[ms] signout successfully",
32
- "text.user registered successfully": "[ms] user registered successfully. find your email to activate account",
33
- "text.user activated successfully": "[ms] user activated successfully",
34
- "text.password reset email sent": "[ms] password reset email sent",
35
- "text.verification email sent": "[ms] verification email sent",
36
- "error.confirm password not matched": "[ms] new password and confirm password is not matched",
37
- "error.domain not allowed": "[ms] user not allowed domain `{subdomain}`",
38
- "error.domain mismatch": "[ms] certificate is not for this domain",
39
- "error.failed to find x": "[ms] failed to find {x}",
40
- "error.password should match the rule": "[ms] password should match following rule. ${rule}",
41
- "error.password used in the past": "[ms] password used in the past",
42
- "error.subdomain not found": "[ms] domain not found",
43
- "error.token or password is invalid": "[ms] token or password is invalid",
44
- "error.unavailable-domain": "[ms] unavailable domain",
45
- "error.user not found": "pengguna tidak wujud",
46
- "error.user duplicated": "emel telah diguna oleh akaun lain",
47
- "error.user or verification token not found": "[ms] user or verification token not found",
48
- "error.user validation failed": "[ms] user validation failed",
49
- "error.user not activated": "[ms] user is not activated",
50
- "error.x is not a member of y": "[ms] {x} is not a member of {y}",
51
- "privilege.category.system": "[ms] system setting",
52
- "privilege.description": "[ms] to {name} {category} data",
53
- "privilege.name.mutation": "[ms] edit",
54
- "privilege.name.query": "[ms] read"
2
+ "error.confirm password not matched": "Kata laluan baru dan pengesahan kata laluan tidak sepadan",
3
+ "error.domain mismatch": "Sijil tidak sesuai untuk domain ini",
4
+ "error.domain not allowed": "Pengguna tidak dibenarkan domain `{subdomain}`",
5
+ "error.failed to find x": "Gagal mencari {x}",
6
+ "error.password should match the rule": "Kata laluan harus mematuhi peraturan berikut. ${rule}",
7
+ "error.password used in the past": "Kata laluan telah digunakan dalam masa lampau",
8
+ "error.subdomain not found": "Domain tidak ditemui",
9
+ "error.token or password is invalid": "Token atau kata laluan tidak sah",
10
+ "error.unavailable-domain": "Domain tidak tersedia",
11
+ "error.user duplicated": "Emel telah digunakan oleh akaun lain",
12
+ "error.user not activated": "Pengguna tidak diaktifkan",
13
+ "error.user not found": "Pengguna tidak ditemui",
14
+ "error.user or verification token not found": "Pengguna atau token pengesahan tidak ditemui",
15
+ "error.user validation failed": "Validasi pengguna gagal",
16
+ "error.x is not a member of y": "{x} bukan ahli {y}",
17
+ "field.active": "Aktif",
18
+ "field.appliance_id": "Perkakas",
19
+ "field.brand": "Jenama",
20
+ "field.category": "Kategori",
21
+ "field.email": "E-mel",
22
+ "field.model": "Model",
23
+ "field.password": "Kata laluan",
24
+ "field.privileges": "Keistimewaan",
25
+ "field.roles": "Peranan",
26
+ "field.token": "Token",
27
+ "field.user": "Pengguna",
28
+ "field.user_account": "Akaun pengguna",
29
+ "field.user_type": "Jenis pengguna",
30
+ "label.partner": "Rakan kongsi",
31
+ "privilege.category.system": "Tetapan sistem",
32
+ "privilege.description": "Untuk {name} data {category}",
33
+ "privilege.name.mutation": "Sunting",
34
+ "privilege.name.query": "Baca",
35
+ "text.account is reactivated": "Akaun telah diaktifkan semula",
36
+ "text.delete account succeed": "Berjaya memadam akaun",
37
+ "text.inactive user": "Pengguna tidak aktif",
38
+ "text.invalid verification token": "Token pengesahan tidak sah",
39
+ "text.invitation email sent": "E-mel jemputan telah dihantar",
40
+ "text.password changed successfully": "Kata laluan berjaya diubah",
41
+ "text.password reset email sent": "E-mel reset kata laluan telah dihantar",
42
+ "text.password reset succeed": "Reset kata laluan berjaya",
43
+ "text.pattern_atleast_1_digit": "Sekurang-kurangnya 1 aksara digit",
44
+ "text.pattern_atleast_1_lowercase": "Sekurang-kurangnya 1 aksara kecil",
45
+ "text.pattern_atleast_1_special": "Sekurang-kurangnya 1 aksara istimewa (!@#$%^&*())",
46
+ "text.pattern_atleast_1_uppercase": "Sekurang-kurangnya 1 aksara besar",
47
+ "text.pattern_minimum_charaters": "Minimum {length} aksara",
48
+ "text.pattern_not_allowed": "Tidak dibenarkan aksara berulang",
49
+ "text.profile changed successfully": "Profil berjaya diubah",
50
+ "text.result": "Hasil",
51
+ "text.signout successfully": "Berjaya keluar",
52
+ "text.user activated successfully": "Pengguna diaktifkan dengan berjaya",
53
+ "text.user registered successfully": "Pengguna berjaya didaftarkan. Cari e-mel anda untuk mengaktifkan akaun",
54
+ "text.verification email sent": "E-mel pengesahan telah dihantar"
55
55
  }
@@ -1,55 +1,55 @@
1
1
  {
2
- "field.email": "电子邮件地址",
3
- "field.password": "密码",
4
- "field.token": "符记",
2
+ "error.confirm password not matched": "新密码与确认密码不匹配!",
3
+ "error.domain mismatch": "证书不适用于该域!",
4
+ "error.domain not allowed": "用户无权限使用`{subdomain}`域!",
5
+ "error.failed to find x": "查询{x}失败!",
6
+ "error.password should match the rule": "密码应符合以下规则。${rule}",
7
+ "error.password used in the past": "使用过的密码!",
8
+ "error.subdomain not found": "用户域查询失败!",
9
+ "error.token or password is invalid": "令牌或密码无效!",
10
+ "error.unavailable-domain": "不可用的域名",
11
+ "error.user duplicated": "有一个用户帐户使用相同的电子邮件",
12
+ "error.user not activated": "用户未激活!",
13
+ "error.user not found": "找不到用户",
14
+ "error.user or verification token not found": "找不到用户或验证令牌。",
15
+ "error.user validation failed": "用户验证失败!",
16
+ "error.x is not a member of y": "{x}不是{y}的成员",
17
+ "field.active": "激活",
5
18
  "field.appliance_id": "终端机ID",
6
19
  "field.brand": "品牌",
7
- "field.model": "模型",
8
- "field.active": "激活",
9
20
  "field.category": "分类",
10
- "field.roles": "角色",
21
+ "field.email": "电子邮件地址",
22
+ "field.model": "模型",
23
+ "field.password": "密码",
11
24
  "field.privileges": "权限",
25
+ "field.roles": "角色",
26
+ "field.token": "符记",
12
27
  "field.user": "用户",
13
- "field.user_type": "用户类型",
14
28
  "field.user_account": "用户账号",
29
+ "field.user_type": "用户类型",
15
30
  "label.partner": "合作伙伴",
31
+ "privilege.category.system": "系统配置",
32
+ "privilege.description": "{name} {category}数据",
33
+ "privilege.name.mutation": "编辑",
34
+ "privilege.name.query": "查询",
16
35
  "text.account is reactivated": "账户已经重新激活。",
17
36
  "text.delete account succeed": "已成功删除账号。",
18
37
  "text.inactive user": "未激活用账号。",
19
38
  "text.invalid verification token": "令牌无效。",
20
39
  "text.invitation email sent": "成功发送邀请电子邮件。",
21
- "text.pattern_minimum_charaters": "最少未字符长度为{length}",
22
- "text.pattern_atleast_1_lowercase": "至少1个小写字母",
23
- "text.pattern_atleast_1_uppercase": "至少1个大写字母",
40
+ "text.password changed successfully": "密码更改成功。",
41
+ "text.password reset email sent": "已发送密码重置邮件。",
42
+ "text.password reset succeed": "密码重置成功。",
24
43
  "text.pattern_atleast_1_digit": "至少1位数字字符",
44
+ "text.pattern_atleast_1_lowercase": "至少1个小写字母",
25
45
  "text.pattern_atleast_1_special": "至少1个特殊字符(!@#$%^&*())",
46
+ "text.pattern_atleast_1_uppercase": "至少1个大写字母",
47
+ "text.pattern_minimum_charaters": "最少未字符长度为{length}",
26
48
  "text.pattern_not_allowed": "不允许重复字符",
27
- "text.password reset succeed": "密码重置成功。",
28
- "text.password changed successfully": "密码更改成功。",
29
49
  "text.profile changed successfully": "个人资料更改成功。",
30
50
  "text.result": "结果",
31
51
  "text.signout successfully": "登出成功。",
32
- "text.user registered successfully": "用户注册成功。 请查看电子邮件以激活帐户。",
33
52
  "text.user activated successfully": "用户激活成功",
34
- "text.password reset email sent": "已发送密码重置邮件。",
35
- "text.verification email sent": "验证邮件已发送",
36
- "error.confirm password not matched": "新密码与确认密码不匹配!",
37
- "error.domain not allowed": "用户无权限使用`{subdomain}`域!",
38
- "error.domain mismatch": "证书不适用于该域!",
39
- "error.failed to find x": "查询{x}失败!",
40
- "error.password should match the rule": "密码应符合以下规则。${rule}",
41
- "error.password used in the past": "使用过的密码!",
42
- "error.subdomain not found": "用户域查询失败!",
43
- "error.token or password is invalid": "令牌或密码无效!",
44
- "error.unavailable-domain": "[zh] unavailable domain",
45
- "error.user not found": "找不到用户",
46
- "error.user duplicated": "有一个用户帐户使用相同的电子邮件",
47
- "error.user or verification token not found": "找不到用户或验证令牌。",
48
- "error.user validation failed": "用户验证失败!",
49
- "error.user not activated": "用户未激活!",
50
- "error.x is not a member of y": "{x}不是{y}的成员",
51
- "privilege.category.system": "系统配置",
52
- "privilege.description": "{name} {category}数据",
53
- "privilege.name.mutation": "编辑",
54
- "privilege.name.query": "查询"
55
- }
53
+ "text.user registered successfully": "用户注册成功。 请查看电子邮件以激活帐户。",
54
+ "text.verification email sent": "验证邮件已发送"
55
+ }