@things-factory/auth-base 6.2.6 → 6.2.10

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 (45) hide show
  1. package/client/auth.ts +19 -6
  2. package/client/bootstrap.ts +1 -1
  3. package/client/directive/privileged.ts +2 -38
  4. package/client/index.ts +1 -0
  5. package/client/profiled.ts +78 -0
  6. package/config/config.development.js +32 -0
  7. package/config/config.production.js +32 -0
  8. package/dist-client/auth.d.ts +7 -0
  9. package/dist-client/auth.js +11 -5
  10. package/dist-client/auth.js.map +1 -1
  11. package/dist-client/bootstrap.js +1 -1
  12. package/dist-client/bootstrap.js.map +1 -1
  13. package/dist-client/directive/privileged.d.ts +0 -6
  14. package/dist-client/directive/privileged.js +2 -21
  15. package/dist-client/directive/privileged.js.map +1 -1
  16. package/dist-client/index.d.ts +1 -0
  17. package/dist-client/index.js +1 -0
  18. package/dist-client/index.js.map +1 -1
  19. package/dist-client/profiled.d.ts +10 -0
  20. package/dist-client/profiled.js +52 -0
  21. package/dist-client/profiled.js.map +1 -0
  22. package/dist-client/tsconfig.tsbuildinfo +1 -1
  23. package/dist-server/router/auth-private-process-router.js +3 -1
  24. package/dist-server/router/auth-private-process-router.js.map +1 -1
  25. package/dist-server/router/auth-public-process-router.js +29 -9
  26. package/dist-server/router/auth-public-process-router.js.map +1 -1
  27. package/dist-server/router/auth-signin-router.js +7 -1
  28. package/dist-server/router/auth-signin-router.js.map +1 -1
  29. package/dist-server/router/auth-signup-router.js +53 -44
  30. package/dist-server/router/auth-signup-router.js.map +1 -1
  31. package/dist-server/router/oauth2/oauth2-authorize-router.js +6 -1
  32. package/dist-server/router/oauth2/oauth2-authorize-router.js.map +1 -1
  33. package/dist-server/service/privilege/privilege-directive.js +1 -1
  34. package/dist-server/service/privilege/privilege-directive.js.map +1 -1
  35. package/dist-server/service/role/role-query.js +1 -1
  36. package/dist-server/service/role/role-query.js.map +1 -1
  37. package/dist-server/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +3 -3
  39. package/server/router/auth-private-process-router.ts +3 -1
  40. package/server/router/auth-public-process-router.ts +29 -9
  41. package/server/router/auth-signin-router.ts +8 -1
  42. package/server/router/auth-signup-router.ts +63 -53
  43. package/server/router/oauth2/oauth2-authorize-router.ts +7 -1
  44. package/server/service/privilege/privilege-directive.ts +1 -1
  45. package/server/service/role/role-query.ts +1 -1
package/client/auth.ts CHANGED
@@ -12,7 +12,14 @@ const HEADER_JSON = {
12
12
  Accept: 'application/json'
13
13
  }
14
14
  type AuthEventName = 'profile' | 'signin' | 'signout' | 'presignout' | 'passwordchange' | 'error'
15
- type AuthEventHandler = (e?: { accessToken?: string; credential?: string; domains: any[]; domain: any }) => void
15
+ type AuthEventHandler = (e?: {
16
+ accessToken?: string
17
+ credential?: string
18
+ domains: any[]
19
+ domain: any
20
+ languages?: { code: string; display: string }[]
21
+ privileges?: any[]
22
+ }) => void
16
23
  type AuthErrorHandler = (err: any) => void
17
24
 
18
25
  class ClientAuth {
@@ -39,6 +46,8 @@ class ClientAuth {
39
46
  private accessToken?: string
40
47
  private domains: any[] = []
41
48
  private domain: any
49
+ private languages: { code: string; display: string }[] = []
50
+ private privileges: any[] = []
42
51
 
43
52
  constructor() {
44
53
  document.addEventListener('auth-required', this.authRequiredEventListener)
@@ -58,7 +67,7 @@ class ClientAuth {
58
67
  특별히 event 가 profile 인 경우에는 이미 fetch된 credential이 있다면, 콜백을 해준다.
59
68
  시스템 bootstrap에서 profile 이벤트가 사용되는 경우가 많은데, profile도 매우 초기에 fetch 되므로 레이스컨디션이 발생할 수 있기 때문에, 확실하게 event 콜백을 보장하기 위해서이다.
60
69
  */
61
- handler({ credential: this._credential, domains: this.domains, domain: this.domain })
70
+ handler({ credential: this._credential, domains: this.domains, domain: this.domain, languages: this.languages })
62
71
  }
63
72
  }
64
73
 
@@ -86,10 +95,12 @@ class ClientAuth {
86
95
  }
87
96
  }
88
97
 
89
- private onProfileFetched({ credential, accessToken, domains, domain }) {
98
+ private onProfileFetched({ credential, accessToken, domains, domain, languages, privileges }) {
90
99
  this._credential = credential
91
100
  this.domains = domains
92
101
  this.domain = domain
102
+ this.languages = languages
103
+ this.privileges = privileges
93
104
 
94
105
  if (accessToken && !this.accessToken) {
95
106
  /*
@@ -97,10 +108,10 @@ class ClientAuth {
97
108
  이 경우는 signin 이벤트리스너들을 호출해서 authenticated 상태로 되도록 유도한다.
98
109
  */
99
110
  this.accessToken = accessToken
100
- this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain }))
111
+ this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain, languages, privileges }))
101
112
  }
102
113
  accessToken && (this.accessToken = accessToken)
103
- this.listeners.profile.forEach(handler => handler({ credential, domains, domain }))
114
+ this.listeners.profile.forEach(handler => handler({ credential, domains, domain, languages, privileges }))
104
115
  }
105
116
 
106
117
  private async onPreSignout() {
@@ -243,7 +254,9 @@ class ClientAuth {
243
254
  credential: data.user,
244
255
  accessToken: data.token,
245
256
  domains: data.domains,
246
- domain: data.domain
257
+ domain: data.domain,
258
+ languages: data.languages,
259
+ privileges: data.privileges
247
260
  })
248
261
 
249
262
  return
@@ -11,7 +11,7 @@ export default function bootstrap() {
11
11
  auth: reducerAuth
12
12
  })
13
13
 
14
- auth.on('profile', ({ credential, domains, domain }) => {
14
+ auth.on('profile', ({ credential, domains, domain, languages }) => {
15
15
  store.dispatch(
16
16
  updateAuthenticated({
17
17
  authenticated: true
@@ -1,42 +1,6 @@
1
1
  import { nothing } from 'lit'
2
2
  import { directive, AsyncDirective } from 'lit/async-directive.js'
3
-
4
- import { auth } from '../auth'
5
-
6
- var profileResolved = false
7
- var user
8
-
9
- const profileReady = new Promise<void>(resolve => {
10
- auth.on('profile', ({ credential, domains, domain }) => {
11
- profileResolved = true
12
- user = credential
13
- resolve()
14
- })
15
- })
16
-
17
- export async function hasPrivilege({
18
- name,
19
- category,
20
- domainOwnerGranted,
21
- superUserGranted
22
- }: {
23
- name?: string
24
- category?: string
25
- domainOwnerGranted?: boolean
26
- superUserGranted?: boolean
27
- }) {
28
- if (!profileResolved) {
29
- await profileReady
30
- }
31
-
32
- const { privileges, owner, super: superUser } = user
33
-
34
- return (
35
- (domainOwnerGranted && owner) ||
36
- (superUserGranted && superUser) ||
37
- (name && category && (privileges || []).find(p => p.name == name && p.category == category))
38
- )
39
- }
3
+ import { hasPrivilege } from '../profiled'
40
4
 
41
5
  class PrivilegedDirective extends AsyncDirective {
42
6
  async render(
@@ -47,7 +11,7 @@ class PrivilegedDirective extends AsyncDirective {
47
11
  superUserGranted?: boolean
48
12
  },
49
13
  trueResult: any,
50
- falseResult: any = nothing // 만약 값을 제공하지 않으면 기본값으로 'nothing'을 사용
14
+ falseResult: any = nothing
51
15
  ) {
52
16
  this.setValue((await hasPrivilege(privilege)) ? trueResult : falseResult)
53
17
  }
package/client/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './auth'
2
+ export * from './profiled'
2
3
  export * from './directive/privileged'
@@ -0,0 +1,78 @@
1
+ import { auth } from './auth'
2
+
3
+ var profileResolved = false
4
+ var user
5
+ var languages
6
+ var privileges
7
+ var domain
8
+ var domains
9
+
10
+ const profileReady = new Promise<void>(resolve => {
11
+ auth.on('profile', (data: { credential; domains; domain; languages; privileges }) => {
12
+ profileResolved = true
13
+
14
+ user = data.credential
15
+ languages = data.languages
16
+ domain = data.domain
17
+ domains = data.domains
18
+ privileges = data.privileges
19
+
20
+ resolve()
21
+ })
22
+ })
23
+
24
+ export async function hasPrivilege({
25
+ name,
26
+ category,
27
+ domainOwnerGranted,
28
+ superUserGranted
29
+ }: {
30
+ name?: string
31
+ category?: string
32
+ domainOwnerGranted?: boolean
33
+ superUserGranted?: boolean
34
+ }) {
35
+ if (!profileResolved) {
36
+ await profileReady
37
+ }
38
+
39
+ const { privileges, owner, super: superUser } = user
40
+
41
+ return (
42
+ (domainOwnerGranted && owner) ||
43
+ (superUserGranted && superUser) ||
44
+ (name && category && (privileges || []).find(p => p.name == name && p.category == category))
45
+ )
46
+ }
47
+
48
+ export async function getLanguages() {
49
+ if (!profileResolved) {
50
+ await profileReady
51
+ }
52
+
53
+ return languages
54
+ }
55
+
56
+ export async function getDomain() {
57
+ if (!profileResolved) {
58
+ await profileReady
59
+ }
60
+
61
+ return domain
62
+ }
63
+
64
+ export async function getDomains() {
65
+ if (!profileResolved) {
66
+ await profileReady
67
+ }
68
+
69
+ return domains
70
+ }
71
+
72
+ export async function getPrivileges() {
73
+ if (!profileResolved) {
74
+ await profileReady
75
+ }
76
+
77
+ return privileges
78
+ }
@@ -13,6 +13,38 @@ module.exports = {
13
13
  history: 2,
14
14
  defaultPassword: false
15
15
  },
16
+ /*
17
+ Only When 'disableUserSignupProcess' is set to false,
18
+ a user-initiated user registration process is provided.
19
+ When this value is true, the 'defaultPassword' for the password must be configured.
20
+ */
21
+ disableUserSignupProcess: false,
22
+ i18n: {
23
+ languages: [
24
+ {
25
+ code: 'en-US',
26
+ display: 'English'
27
+ },
28
+ {
29
+ code: 'ko-KR',
30
+ display: '한국어'
31
+ },
32
+ {
33
+ code: 'zh-CN',
34
+ display: '中文'
35
+ },
36
+ {
37
+ code: 'ja-JP',
38
+ display: 'にほんご'
39
+ },
40
+ {
41
+ code: 'ms-MY',
42
+ display: 'Bahasa Malaysia'
43
+ }
44
+ ],
45
+ defaultLanguage: 'en-US',
46
+ disableUserFavoredLanguage: false
47
+ },
16
48
  accessTokenCookieKey: 'access_token',
17
49
  applianceJwtExpiresIn: '1y',
18
50
  publicHomeRoute: '/public/home'
@@ -12,6 +12,38 @@ module.exports = {
12
12
  looseCharacterLength: 15,
13
13
  history: 4
14
14
  },
15
+ /*
16
+ Only When 'disableUserSignupProcess' is set to false,
17
+ a user-initiated user registration process is provided.
18
+ When this value is true, the 'defaultPassword' for the password must be configured.
19
+ */
20
+ disableUserSignupProcess: false,
21
+ i18n: {
22
+ languages: [
23
+ {
24
+ code: 'en-US',
25
+ display: 'English'
26
+ },
27
+ {
28
+ code: 'ko-KR',
29
+ display: '한국어'
30
+ },
31
+ {
32
+ code: 'zh-CN',
33
+ display: '中文'
34
+ },
35
+ {
36
+ code: 'ja-JP',
37
+ display: 'にほんご'
38
+ },
39
+ {
40
+ code: 'ms-MY',
41
+ display: 'Bahasa Malaysia'
42
+ }
43
+ ],
44
+ defaultLanguage: 'en-US',
45
+ disableUserFavoredLanguage: false
46
+ },
15
47
  accessTokenCookieKey: 'access_token',
16
48
  applianceJwtExpiresIn: '1y',
17
49
  publicHomeRoute: '/public/home'
@@ -4,6 +4,11 @@ type AuthEventHandler = (e?: {
4
4
  credential?: string;
5
5
  domains: any[];
6
6
  domain: any;
7
+ languages?: {
8
+ code: string;
9
+ display: string;
10
+ }[];
11
+ privileges?: any[];
7
12
  }) => void;
8
13
  type AuthErrorHandler = (err: any) => void;
9
14
  declare class ClientAuth {
@@ -14,6 +19,8 @@ declare class ClientAuth {
14
19
  private accessToken?;
15
20
  private domains;
16
21
  private domain;
22
+ private languages;
23
+ private privileges;
17
24
  constructor();
18
25
  on(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler): void;
19
26
  off(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler): void;
@@ -23,6 +23,8 @@ class ClientAuth {
23
23
  this.authRequiredEventListener = this.onAuthRequired.bind(this);
24
24
  this.activateRequiredEventListener = this.onActivateRequired.bind(this);
25
25
  this.domains = [];
26
+ this.languages = [];
27
+ this.privileges = [];
26
28
  document.addEventListener('auth-required', this.authRequiredEventListener);
27
29
  document.addEventListener('activate-required', this.activateRequiredEventListener);
28
30
  }
@@ -39,7 +41,7 @@ class ClientAuth {
39
41
  특별히 event 가 profile 인 경우에는 이미 fetch된 credential이 있다면, 콜백을 해준다.
40
42
  시스템 bootstrap에서 profile 이벤트가 사용되는 경우가 많은데, profile도 매우 초기에 fetch 되므로 레이스컨디션이 발생할 수 있기 때문에, 확실하게 event 콜백을 보장하기 위해서이다.
41
43
  */
42
- handler({ credential: this._credential, domains: this.domains, domain: this.domain });
44
+ handler({ credential: this._credential, domains: this.domains, domain: this.domain, languages: this.languages });
43
45
  }
44
46
  }
45
47
  off(event, handler) {
@@ -64,20 +66,22 @@ class ClientAuth {
64
66
  error: []
65
67
  };
66
68
  }
67
- onProfileFetched({ credential, accessToken, domains, domain }) {
69
+ onProfileFetched({ credential, accessToken, domains, domain, languages, privileges }) {
68
70
  this._credential = credential;
69
71
  this.domains = domains;
70
72
  this.domain = domain;
73
+ this.languages = languages;
74
+ this.privileges = privileges;
71
75
  if (accessToken && !this.accessToken) {
72
76
  /*
73
77
  기존에 세션을 가지거나, 액세스토큰으로 인증된 경우,
74
78
  이 경우는 signin 이벤트리스너들을 호출해서 authenticated 상태로 되도록 유도한다.
75
79
  */
76
80
  this.accessToken = accessToken;
77
- this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain }));
81
+ this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain, languages, privileges }));
78
82
  }
79
83
  accessToken && (this.accessToken = accessToken);
80
- this.listeners.profile.forEach(handler => handler({ credential, domains, domain }));
84
+ this.listeners.profile.forEach(handler => handler({ credential, domains, domain, languages, privileges }));
81
85
  }
82
86
  async onPreSignout() {
83
87
  for (let onpresignout of this.listeners.presignout) {
@@ -200,7 +204,9 @@ class ClientAuth {
200
204
  credential: data.user,
201
205
  accessToken: data.token,
202
206
  domains: data.domains,
203
- domain: data.domain
207
+ domain: data.domain,
208
+ languages: data.languages,
209
+ privileges: data.privileges
204
210
  });
205
211
  return;
206
212
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../client/auth.ts"],"names":[],"mappings":"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","sourcesContent":["/* [ AUTH PATH ]\n signinPath = '/auth/signin'\n signoutPath = '/auth/signout'\n profilePath = '/auth/profile'\n updateProfilePath = '/auth/update-profile'\n changepassPath = '/auth/change-pass'\n deleteUserPath = '/auth/delete-user'\n*/\n\nconst HEADER_JSON = {\n 'Content-Type': 'application/json',\n Accept: 'application/json'\n}\ntype AuthEventName = 'profile' | 'signin' | 'signout' | 'presignout' | 'passwordchange' | 'error'\ntype AuthEventHandler = (e?: { accessToken?: string; credential?: string; domains: any[]; domain: any }) => void\ntype AuthErrorHandler = (err: any) => void\n\nclass ClientAuth {\n private listeners: {\n profile: AuthEventHandler[]\n signout: AuthEventHandler[]\n signin: AuthEventHandler[]\n presignout: AuthEventHandler[]\n passwordchange: AuthEventHandler[]\n error: AuthErrorHandler[]\n } = {\n profile: [],\n signout: [],\n signin: [],\n presignout: [],\n passwordchange: [],\n error: []\n }\n\n private authRequiredEventListener = this.onAuthRequired.bind(this)\n private activateRequiredEventListener = this.onActivateRequired.bind(this)\n\n private _credential: any\n private accessToken?: string\n private domains: any[] = []\n private domain: any\n\n constructor() {\n document.addEventListener('auth-required', this.authRequiredEventListener)\n document.addEventListener('activate-required', this.activateRequiredEventListener)\n }\n\n on(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler) {\n var listeners = this.listeners[event]\n if (listeners) {\n listeners.push(handler)\n } else {\n console.log('unknown event', event)\n }\n\n if (event == 'profile' && this._credential) {\n /* \n 특별히 event 가 profile 인 경우에는 이미 fetch된 credential이 있다면, 콜백을 해준다. \n 시스템 bootstrap에서 profile 이벤트가 사용되는 경우가 많은데, profile도 매우 초기에 fetch 되므로 레이스컨디션이 발생할 수 있기 때문에, 확실하게 event 콜백을 보장하기 위해서이다.\n */\n handler({ credential: this._credential, domains: this.domains, domain: this.domain })\n }\n }\n\n off(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler) {\n var listeners = this.listeners[event]\n if (listeners) {\n let idx = listeners.indexOf(handler)\n idx >= 0 && listeners.splice(idx, 1)\n } else {\n console.log('unknown event', event)\n }\n }\n\n dispose() {\n document.removeEventListener('auth-required', this.authRequiredEventListener)\n document.removeEventListener('activate-required', this.activateRequiredEventListener)\n\n this.listeners = {\n profile: [],\n signin: [],\n signout: [],\n presignout: [],\n passwordchange: [],\n error: []\n }\n }\n\n private onProfileFetched({ credential, accessToken, domains, domain }) {\n this._credential = credential\n this.domains = domains\n this.domain = domain\n\n if (accessToken && !this.accessToken) {\n /*\n 기존에 세션을 가지거나, 액세스토큰으로 인증된 경우,\n 이 경우는 signin 이벤트리스너들을 호출해서 authenticated 상태로 되도록 유도한다.\n */\n this.accessToken = accessToken\n this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain }))\n }\n accessToken && (this.accessToken = accessToken)\n this.listeners.profile.forEach(handler => handler({ credential, domains, domain }))\n }\n\n private async onPreSignout() {\n for (let onpresignout of this.listeners.presignout) {\n await onpresignout()\n }\n }\n\n private onAuthError(error) {\n /* signin, signup 과정에서 에러가 발생한 경우 */\n this.listeners?.error.forEach(handler => handler(error))\n }\n\n private onPasswordChanged(result) {\n //event is passwordchange, handler is result\n this.listeners?.passwordchange.forEach(handler => handler(result))\n }\n\n private onAuthRequired(e) {\n console.warn('authentication required')\n let url = new URL(window.location.href)\n url.pathname = '/auth/signin'\n url.searchParams.append('redirect_to', window.location.href)\n\n window.location.href = url.href\n }\n\n private onActivateRequired(e) {\n console.warn('activate required')\n var params = new URLSearchParams()\n params.append('email', e.email)\n\n window.location.replace(`/auth/activate?${params}`)\n }\n\n get credential() {\n return this._credential\n }\n\n route(path, redirected) {\n /* history에 남긴다. redirected된 상태임을 남긴다. */\n const location = window.location\n const origin = location.origin || location.protocol + '//' + location.host\n const href = `${origin}${path}`\n\n if (location.pathname === path) return\n\n // popstate 이벤트가 history.back() 에서만 발생하므로\n // 히스토리에 두번을 넣고 back()을 호출하는 편법을 사용함.\n // forward history가 한번 남는 문제가 있으나 signin 프로세스 중에만 발생하므로 큰 문제는 아님.\n // 이 로직은 login process가 어플리케이션 구조에 종속되는 것을 최소화하기 위함임.\n // 예를 들면, redux 구조에 들어가지 않아도 로그인 프로세스가 동작하도록 한 것임.\n window.history.pushState({ redirected }, '', href)\n window.history.pushState({}, '', href)\n\n window.history.back()\n }\n\n async updateProfile(formProps) {\n const response = await fetch('/auth/update-profile', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(formProps)\n })\n\n const message = await response.text()\n if (response.ok) {\n return message\n }\n\n throw new Error(message)\n }\n\n async changePassword(formProps) {\n try {\n const response = await fetch('/auth/change-pass', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(formProps)\n })\n\n const message = await response.text()\n if (response.ok) {\n this.onPasswordChanged({ message })\n } else {\n this.onAuthError({ message })\n }\n } catch (e) {\n this.onAuthError(e)\n }\n }\n\n async deleteUser(params) {\n const response = await fetch('/auth/delete-user', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(params)\n })\n\n const message = await response.text()\n if (response.ok) {\n return message\n } else {\n throw new Error(message)\n }\n }\n\n async profile() {\n if (sessionStorage.getItem('ThingsFactory-UseExternServer')) {\n return\n }\n\n try {\n var searchParams = new URLSearchParams(location.search)\n var token = searchParams.get('token')\n var headers = JSON.parse(JSON.stringify(HEADER_JSON))\n\n if (token) {\n headers.authorization = `Bearer ${token}`\n }\n\n const response = await fetch('/auth/profile', {\n method: 'GET',\n credentials: 'include',\n headers\n })\n\n if (response.ok) {\n if (response.redirected) {\n location.href = response.url\n return\n }\n\n const data = await response.json()\n\n this.onProfileFetched({\n credential: data.user,\n accessToken: data.token,\n domains: data.domains,\n domain: data.domain\n })\n\n return\n }\n } catch (e) {\n this.onAuthError(e)\n }\n }\n\n async signout() {\n await this.onPreSignout()\n\n window.location.href = '/auth/signout'\n }\n}\n\nexport const auth = new ClientAuth()\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../client/auth.ts"],"names":[],"mappings":"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","sourcesContent":["/* [ AUTH PATH ]\n signinPath = '/auth/signin'\n signoutPath = '/auth/signout'\n profilePath = '/auth/profile'\n updateProfilePath = '/auth/update-profile'\n changepassPath = '/auth/change-pass'\n deleteUserPath = '/auth/delete-user'\n*/\n\nconst HEADER_JSON = {\n 'Content-Type': 'application/json',\n Accept: 'application/json'\n}\ntype AuthEventName = 'profile' | 'signin' | 'signout' | 'presignout' | 'passwordchange' | 'error'\ntype AuthEventHandler = (e?: {\n accessToken?: string\n credential?: string\n domains: any[]\n domain: any\n languages?: { code: string; display: string }[]\n privileges?: any[]\n}) => void\ntype AuthErrorHandler = (err: any) => void\n\nclass ClientAuth {\n private listeners: {\n profile: AuthEventHandler[]\n signout: AuthEventHandler[]\n signin: AuthEventHandler[]\n presignout: AuthEventHandler[]\n passwordchange: AuthEventHandler[]\n error: AuthErrorHandler[]\n } = {\n profile: [],\n signout: [],\n signin: [],\n presignout: [],\n passwordchange: [],\n error: []\n }\n\n private authRequiredEventListener = this.onAuthRequired.bind(this)\n private activateRequiredEventListener = this.onActivateRequired.bind(this)\n\n private _credential: any\n private accessToken?: string\n private domains: any[] = []\n private domain: any\n private languages: { code: string; display: string }[] = []\n private privileges: any[] = []\n\n constructor() {\n document.addEventListener('auth-required', this.authRequiredEventListener)\n document.addEventListener('activate-required', this.activateRequiredEventListener)\n }\n\n on(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler) {\n var listeners = this.listeners[event]\n if (listeners) {\n listeners.push(handler)\n } else {\n console.log('unknown event', event)\n }\n\n if (event == 'profile' && this._credential) {\n /* \n 특별히 event 가 profile 인 경우에는 이미 fetch된 credential이 있다면, 콜백을 해준다. \n 시스템 bootstrap에서 profile 이벤트가 사용되는 경우가 많은데, profile도 매우 초기에 fetch 되므로 레이스컨디션이 발생할 수 있기 때문에, 확실하게 event 콜백을 보장하기 위해서이다.\n */\n handler({ credential: this._credential, domains: this.domains, domain: this.domain, languages: this.languages })\n }\n }\n\n off(event: AuthEventName, handler: AuthEventHandler | AuthErrorHandler) {\n var listeners = this.listeners[event]\n if (listeners) {\n let idx = listeners.indexOf(handler)\n idx >= 0 && listeners.splice(idx, 1)\n } else {\n console.log('unknown event', event)\n }\n }\n\n dispose() {\n document.removeEventListener('auth-required', this.authRequiredEventListener)\n document.removeEventListener('activate-required', this.activateRequiredEventListener)\n\n this.listeners = {\n profile: [],\n signin: [],\n signout: [],\n presignout: [],\n passwordchange: [],\n error: []\n }\n }\n\n private onProfileFetched({ credential, accessToken, domains, domain, languages, privileges }) {\n this._credential = credential\n this.domains = domains\n this.domain = domain\n this.languages = languages\n this.privileges = privileges\n\n if (accessToken && !this.accessToken) {\n /*\n 기존에 세션을 가지거나, 액세스토큰으로 인증된 경우,\n 이 경우는 signin 이벤트리스너들을 호출해서 authenticated 상태로 되도록 유도한다.\n */\n this.accessToken = accessToken\n this.listeners.signin.forEach(handler => handler({ accessToken, domains, domain, languages, privileges }))\n }\n accessToken && (this.accessToken = accessToken)\n this.listeners.profile.forEach(handler => handler({ credential, domains, domain, languages, privileges }))\n }\n\n private async onPreSignout() {\n for (let onpresignout of this.listeners.presignout) {\n await onpresignout()\n }\n }\n\n private onAuthError(error) {\n /* signin, signup 과정에서 에러가 발생한 경우 */\n this.listeners?.error.forEach(handler => handler(error))\n }\n\n private onPasswordChanged(result) {\n //event is passwordchange, handler is result\n this.listeners?.passwordchange.forEach(handler => handler(result))\n }\n\n private onAuthRequired(e) {\n console.warn('authentication required')\n let url = new URL(window.location.href)\n url.pathname = '/auth/signin'\n url.searchParams.append('redirect_to', window.location.href)\n\n window.location.href = url.href\n }\n\n private onActivateRequired(e) {\n console.warn('activate required')\n var params = new URLSearchParams()\n params.append('email', e.email)\n\n window.location.replace(`/auth/activate?${params}`)\n }\n\n get credential() {\n return this._credential\n }\n\n route(path, redirected) {\n /* history에 남긴다. redirected된 상태임을 남긴다. */\n const location = window.location\n const origin = location.origin || location.protocol + '//' + location.host\n const href = `${origin}${path}`\n\n if (location.pathname === path) return\n\n // popstate 이벤트가 history.back() 에서만 발생하므로\n // 히스토리에 두번을 넣고 back()을 호출하는 편법을 사용함.\n // forward history가 한번 남는 문제가 있으나 signin 프로세스 중에만 발생하므로 큰 문제는 아님.\n // 이 로직은 login process가 어플리케이션 구조에 종속되는 것을 최소화하기 위함임.\n // 예를 들면, redux 구조에 들어가지 않아도 로그인 프로세스가 동작하도록 한 것임.\n window.history.pushState({ redirected }, '', href)\n window.history.pushState({}, '', href)\n\n window.history.back()\n }\n\n async updateProfile(formProps) {\n const response = await fetch('/auth/update-profile', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(formProps)\n })\n\n const message = await response.text()\n if (response.ok) {\n return message\n }\n\n throw new Error(message)\n }\n\n async changePassword(formProps) {\n try {\n const response = await fetch('/auth/change-pass', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(formProps)\n })\n\n const message = await response.text()\n if (response.ok) {\n this.onPasswordChanged({ message })\n } else {\n this.onAuthError({ message })\n }\n } catch (e) {\n this.onAuthError(e)\n }\n }\n\n async deleteUser(params) {\n const response = await fetch('/auth/delete-user', {\n method: 'POST',\n credentials: 'include',\n headers: HEADER_JSON,\n body: JSON.stringify(params)\n })\n\n const message = await response.text()\n if (response.ok) {\n return message\n } else {\n throw new Error(message)\n }\n }\n\n async profile() {\n if (sessionStorage.getItem('ThingsFactory-UseExternServer')) {\n return\n }\n\n try {\n var searchParams = new URLSearchParams(location.search)\n var token = searchParams.get('token')\n var headers = JSON.parse(JSON.stringify(HEADER_JSON))\n\n if (token) {\n headers.authorization = `Bearer ${token}`\n }\n\n const response = await fetch('/auth/profile', {\n method: 'GET',\n credentials: 'include',\n headers\n })\n\n if (response.ok) {\n if (response.redirected) {\n location.href = response.url\n return\n }\n\n const data = await response.json()\n\n this.onProfileFetched({\n credential: data.user,\n accessToken: data.token,\n domains: data.domains,\n domain: data.domain,\n languages: data.languages,\n privileges: data.privileges\n })\n\n return\n }\n } catch (e) {\n this.onAuthError(e)\n }\n }\n\n async signout() {\n await this.onPreSignout()\n\n window.location.href = '/auth/signout'\n }\n}\n\nexport const auth = new ClientAuth()\n"]}
@@ -7,7 +7,7 @@ export default function bootstrap() {
7
7
  store.addReducers({
8
8
  auth: reducerAuth
9
9
  });
10
- auth.on('profile', ({ credential, domains, domain }) => {
10
+ auth.on('profile', ({ credential, domains, domain, languages }) => {
11
11
  store.dispatch(updateAuthenticated({
12
12
  authenticated: true
13
13
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../client/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,WAAW,MAAM,iBAAiB,CAAA;AAEzC,OAAO,wBAAwB,CAAA,CAAC,kCAAkC;AAElE,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,KAAK,CAAC,WAAW,CAAC;QAChB,IAAI,EAAE,WAAW;KAClB,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACrD,KAAK,CAAC,QAAQ,CACZ,mBAAmB,CAAC;YAClB,aAAa,EAAE,IAAI;SACpB,CAAQ,CACV,CAAA;QACD,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAQ,CAAC,CAAA;QAC7C,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAQ,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE;QACjC,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAE5B,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;gBACtC,OAAO;aACR;SACF,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;QACpB,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB;SACF,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { store, updateDomains } from '@operato/shell'\n\nimport { updateAuthenticated, updateUser } from './actions/auth'\nimport { auth } from './auth'\nimport reducerAuth from './reducers/auth'\n\nimport './directive/privileged' /* directive 초기화를 보장하기 위해서 호출함. */\n\nexport default function bootstrap() {\n store.addReducers({\n auth: reducerAuth\n })\n\n auth.on('profile', ({ credential, domains, domain }) => {\n store.dispatch(\n updateAuthenticated({\n authenticated: true\n }) as any\n )\n store.dispatch(updateUser(credential) as any)\n store.dispatch(updateDomains(domains, domain) as any)\n })\n\n auth.on('passwordchange', result => {\n let message = result.message\n\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: result.error ? 'error' : 'info',\n message\n }\n })\n )\n })\n\n auth.on('error', ex => {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: ex.message\n }\n })\n )\n })\n}\n"]}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../client/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,WAAW,MAAM,iBAAiB,CAAA;AAEzC,OAAO,wBAAwB,CAAA,CAAC,kCAAkC;AAElE,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,KAAK,CAAC,WAAW,CAAC;QAChB,IAAI,EAAE,WAAW;KAClB,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;QAChE,KAAK,CAAC,QAAQ,CACZ,mBAAmB,CAAC;YAClB,aAAa,EAAE,IAAI;SACpB,CAAQ,CACV,CAAA;QACD,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAQ,CAAC,CAAA;QAC7C,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAQ,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE;QACjC,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAE5B,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;gBACtC,OAAO;aACR;SACF,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;QACpB,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,MAAM,EAAE;gBACN,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB;SACF,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { store, updateDomains } from '@operato/shell'\n\nimport { updateAuthenticated, updateUser } from './actions/auth'\nimport { auth } from './auth'\nimport reducerAuth from './reducers/auth'\n\nimport './directive/privileged' /* directive 초기화를 보장하기 위해서 호출함. */\n\nexport default function bootstrap() {\n store.addReducers({\n auth: reducerAuth\n })\n\n auth.on('profile', ({ credential, domains, domain, languages }) => {\n store.dispatch(\n updateAuthenticated({\n authenticated: true\n }) as any\n )\n store.dispatch(updateUser(credential) as any)\n store.dispatch(updateDomains(domains, domain) as any)\n })\n\n auth.on('passwordchange', result => {\n let message = result.message\n\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: result.error ? 'error' : 'info',\n message\n }\n })\n )\n })\n\n auth.on('error', ex => {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: ex.message\n }\n })\n )\n })\n}\n"]}
@@ -1,10 +1,4 @@
1
1
  import { AsyncDirective } from 'lit/async-directive.js';
2
- export declare function hasPrivilege({ name, category, domainOwnerGranted, superUserGranted }: {
3
- name?: string;
4
- category?: string;
5
- domainOwnerGranted?: boolean;
6
- superUserGranted?: boolean;
7
- }): Promise<any>;
8
2
  declare class PrivilegedDirective extends AsyncDirective {
9
3
  render(privilege: {
10
4
  name?: string;
@@ -1,27 +1,8 @@
1
1
  import { nothing } from 'lit';
2
2
  import { directive, AsyncDirective } from 'lit/async-directive.js';
3
- import { auth } from '../auth';
4
- var profileResolved = false;
5
- var user;
6
- const profileReady = new Promise(resolve => {
7
- auth.on('profile', ({ credential, domains, domain }) => {
8
- profileResolved = true;
9
- user = credential;
10
- resolve();
11
- });
12
- });
13
- export async function hasPrivilege({ name, category, domainOwnerGranted, superUserGranted }) {
14
- if (!profileResolved) {
15
- await profileReady;
16
- }
17
- const { privileges, owner, super: superUser } = user;
18
- return ((domainOwnerGranted && owner) ||
19
- (superUserGranted && superUser) ||
20
- (name && category && (privileges || []).find(p => p.name == name && p.category == category)));
21
- }
3
+ import { hasPrivilege } from '../profiled';
22
4
  class PrivilegedDirective extends AsyncDirective {
23
- async render(privilege, trueResult, falseResult = nothing // 만약 값을 제공하지 않으면 기본값으로 'nothing'을 사용
24
- ) {
5
+ async render(privilege, trueResult, falseResult = nothing) {
25
6
  this.setValue((await hasPrivilege(privilege)) ? trueResult : falseResult);
26
7
  }
27
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"privileged.js","sourceRoot":"","sources":["../../client/directive/privileged.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAElE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE9B,IAAI,eAAe,GAAG,KAAK,CAAA;AAC3B,IAAI,IAAI,CAAA;AAER,MAAM,YAAY,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;IAC/C,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACrD,eAAe,GAAG,IAAI,CAAA;QACtB,IAAI,GAAG,UAAU,CAAA;QACjB,OAAO,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EAMjB;IACC,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAEpD,OAAO,CACL,CAAC,kBAAkB,IAAI,KAAK,CAAC;QAC7B,CAAC,gBAAgB,IAAI,SAAS,CAAC;QAC/B,CAAC,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAC7F,CAAA;AACH,CAAC;AAED,MAAM,mBAAoB,SAAQ,cAAc;IAC9C,KAAK,CAAC,MAAM,CACV,SAKC,EACD,UAAe,EACf,cAAmB,OAAO,CAAC,qCAAqC;;QAEhE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IAC3E,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,mBAAmB,CAAC,CAAA","sourcesContent":["import { nothing } from 'lit'\nimport { directive, AsyncDirective } from 'lit/async-directive.js'\n\nimport { auth } from '../auth'\n\nvar profileResolved = false\nvar user\n\nconst profileReady = new Promise<void>(resolve => {\n auth.on('profile', ({ credential, domains, domain }) => {\n profileResolved = true\n user = credential\n resolve()\n })\n})\n\nexport async function hasPrivilege({\n name,\n category,\n domainOwnerGranted,\n superUserGranted\n}: {\n name?: string\n category?: string\n domainOwnerGranted?: boolean\n superUserGranted?: boolean\n}) {\n if (!profileResolved) {\n await profileReady\n }\n\n const { privileges, owner, super: superUser } = user\n\n return (\n (domainOwnerGranted && owner) ||\n (superUserGranted && superUser) ||\n (name && category && (privileges || []).find(p => p.name == name && p.category == category))\n )\n}\n\nclass PrivilegedDirective extends AsyncDirective {\n async render(\n privilege: {\n name?: string\n category?: string\n domainOwnerGranted?: boolean\n superUserGranted?: boolean\n },\n trueResult: any,\n falseResult: any = nothing // 만약 값을 제공하지 않으면 기본값으로 'nothing'을 사용\n ) {\n this.setValue((await hasPrivilege(privilege)) ? trueResult : falseResult)\n }\n}\n\nexport const privileged = directive(PrivilegedDirective)\n"]}
1
+ {"version":3,"file":"privileged.js","sourceRoot":"","sources":["../../client/directive/privileged.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,mBAAoB,SAAQ,cAAc;IAC9C,KAAK,CAAC,MAAM,CACV,SAKC,EACD,UAAe,EACf,cAAmB,OAAO;QAE1B,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IAC3E,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,mBAAmB,CAAC,CAAA","sourcesContent":["import { nothing } from 'lit'\nimport { directive, AsyncDirective } from 'lit/async-directive.js'\nimport { hasPrivilege } from '../profiled'\n\nclass PrivilegedDirective extends AsyncDirective {\n async render(\n privilege: {\n name?: string\n category?: string\n domainOwnerGranted?: boolean\n superUserGranted?: boolean\n },\n trueResult: any,\n falseResult: any = nothing\n ) {\n this.setValue((await hasPrivilege(privilege)) ? trueResult : falseResult)\n }\n}\n\nexport const privileged = directive(PrivilegedDirective)\n"]}
@@ -1,2 +1,3 @@
1
1
  export * from './auth';
2
+ export * from './profiled';
2
3
  export * from './directive/privileged';
@@ -1,3 +1,4 @@
1
1
  export * from './auth';
2
+ export * from './profiled';
2
3
  export * from './directive/privileged';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,wBAAwB,CAAA","sourcesContent":["export * from './auth'\nexport * from './directive/privileged'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA","sourcesContent":["export * from './auth'\nexport * from './profiled'\nexport * from './directive/privileged'\n"]}
@@ -0,0 +1,10 @@
1
+ export declare function hasPrivilege({ name, category, domainOwnerGranted, superUserGranted }: {
2
+ name?: string;
3
+ category?: string;
4
+ domainOwnerGranted?: boolean;
5
+ superUserGranted?: boolean;
6
+ }): Promise<any>;
7
+ export declare function getLanguages(): Promise<any>;
8
+ export declare function getDomain(): Promise<any>;
9
+ export declare function getDomains(): Promise<any>;
10
+ export declare function getPrivileges(): Promise<any>;
@@ -0,0 +1,52 @@
1
+ import { auth } from './auth';
2
+ var profileResolved = false;
3
+ var user;
4
+ var languages;
5
+ var privileges;
6
+ var domain;
7
+ var domains;
8
+ const profileReady = new Promise(resolve => {
9
+ auth.on('profile', (data) => {
10
+ profileResolved = true;
11
+ user = data.credential;
12
+ languages = data.languages;
13
+ domain = data.domain;
14
+ domains = data.domains;
15
+ privileges = data.privileges;
16
+ resolve();
17
+ });
18
+ });
19
+ export async function hasPrivilege({ name, category, domainOwnerGranted, superUserGranted }) {
20
+ if (!profileResolved) {
21
+ await profileReady;
22
+ }
23
+ const { privileges, owner, super: superUser } = user;
24
+ return ((domainOwnerGranted && owner) ||
25
+ (superUserGranted && superUser) ||
26
+ (name && category && (privileges || []).find(p => p.name == name && p.category == category)));
27
+ }
28
+ export async function getLanguages() {
29
+ if (!profileResolved) {
30
+ await profileReady;
31
+ }
32
+ return languages;
33
+ }
34
+ export async function getDomain() {
35
+ if (!profileResolved) {
36
+ await profileReady;
37
+ }
38
+ return domain;
39
+ }
40
+ export async function getDomains() {
41
+ if (!profileResolved) {
42
+ await profileReady;
43
+ }
44
+ return domains;
45
+ }
46
+ export async function getPrivileges() {
47
+ if (!profileResolved) {
48
+ await profileReady;
49
+ }
50
+ return privileges;
51
+ }
52
+ //# sourceMappingURL=profiled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiled.js","sourceRoot":"","sources":["../client/profiled.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,IAAI,eAAe,GAAG,KAAK,CAAA;AAC3B,IAAI,IAAI,CAAA;AACR,IAAI,SAAS,CAAA;AACb,IAAI,UAAU,CAAA;AACd,IAAI,MAAM,CAAA;AACV,IAAI,OAAO,CAAA;AAEX,MAAM,YAAY,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;IAC/C,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAA4D,EAAE,EAAE;QAClF,eAAe,GAAG,IAAI,CAAA;QAEtB,IAAI,GAAG,IAAI,CAAC,UAAU,CAAA;QACtB,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAC1B,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACpB,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QACtB,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QAE5B,OAAO,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EAMjB;IACC,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAEpD,OAAO,CACL,CAAC,kBAAkB,IAAI,KAAK,CAAC;QAC7B,CAAC,gBAAgB,IAAI,SAAS,CAAC;QAC/B,CAAC,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAC7F,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,YAAY,CAAA;KACnB;IAED,OAAO,UAAU,CAAA;AACnB,CAAC","sourcesContent":["import { auth } from './auth'\n\nvar profileResolved = false\nvar user\nvar languages\nvar privileges\nvar domain\nvar domains\n\nconst profileReady = new Promise<void>(resolve => {\n auth.on('profile', (data: { credential; domains; domain; languages; privileges }) => {\n profileResolved = true\n\n user = data.credential\n languages = data.languages\n domain = data.domain\n domains = data.domains\n privileges = data.privileges\n\n resolve()\n })\n})\n\nexport async function hasPrivilege({\n name,\n category,\n domainOwnerGranted,\n superUserGranted\n}: {\n name?: string\n category?: string\n domainOwnerGranted?: boolean\n superUserGranted?: boolean\n}) {\n if (!profileResolved) {\n await profileReady\n }\n\n const { privileges, owner, super: superUser } = user\n\n return (\n (domainOwnerGranted && owner) ||\n (superUserGranted && superUser) ||\n (name && category && (privileges || []).find(p => p.name == name && p.category == category))\n )\n}\n\nexport async function getLanguages() {\n if (!profileResolved) {\n await profileReady\n }\n\n return languages\n}\n\nexport async function getDomain() {\n if (!profileResolved) {\n await profileReady\n }\n\n return domain\n}\n\nexport async function getDomains() {\n if (!profileResolved) {\n await profileReady\n }\n\n return domains\n}\n\nexport async function getPrivileges() {\n if (!profileResolved) {\n await profileReady\n }\n\n return privileges\n}\n"]}