@contember/react-identity 1.3.0-alpha.14

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 (178) hide show
  1. package/dist/development/components/HasRole.cjs +24 -0
  2. package/dist/development/components/HasRole.cjs.map +1 -0
  3. package/dist/development/components/HasRole.js +24 -0
  4. package/dist/development/components/HasRole.js.map +1 -0
  5. package/dist/development/components/IdentityProvider.cjs +27 -0
  6. package/dist/development/components/IdentityProvider.cjs.map +1 -0
  7. package/dist/development/components/IdentityProvider.js +27 -0
  8. package/dist/development/components/IdentityProvider.js.map +1 -0
  9. package/dist/development/components/IdentityState.cjs +9 -0
  10. package/dist/development/components/IdentityState.cjs.map +1 -0
  11. package/dist/development/components/IdentityState.js +9 -0
  12. package/dist/development/components/IdentityState.js.map +1 -0
  13. package/dist/development/components/LogoutTrigger.cjs +12 -0
  14. package/dist/development/components/LogoutTrigger.cjs.map +1 -0
  15. package/dist/development/components/LogoutTrigger.js +12 -0
  16. package/dist/development/components/LogoutTrigger.js.map +1 -0
  17. package/dist/development/environment/IdentityEnvironmentExtension.cjs +13 -0
  18. package/dist/development/environment/IdentityEnvironmentExtension.cjs.map +1 -0
  19. package/dist/development/environment/IdentityEnvironmentExtension.js +13 -0
  20. package/dist/development/environment/IdentityEnvironmentExtension.js.map +1 -0
  21. package/dist/development/environment/ProjectEnvironmentExtension.cjs +13 -0
  22. package/dist/development/environment/ProjectEnvironmentExtension.cjs.map +1 -0
  23. package/dist/development/environment/ProjectEnvironmentExtension.js +13 -0
  24. package/dist/development/environment/ProjectEnvironmentExtension.js.map +1 -0
  25. package/dist/development/hooks/useFetchIdentity.cjs +51 -0
  26. package/dist/development/hooks/useFetchIdentity.cjs.map +1 -0
  27. package/dist/development/hooks/useFetchIdentity.js +51 -0
  28. package/dist/development/hooks/useFetchIdentity.js.map +1 -0
  29. package/dist/development/hooks/useLogout.cjs +10 -0
  30. package/dist/development/hooks/useLogout.cjs.map +1 -0
  31. package/dist/development/hooks/useLogout.js +10 -0
  32. package/dist/development/hooks/useLogout.js.map +1 -0
  33. package/dist/development/hooks/useProjectUserRoles.cjs +21 -0
  34. package/dist/development/hooks/useProjectUserRoles.cjs.map +1 -0
  35. package/dist/development/hooks/useProjectUserRoles.js +21 -0
  36. package/dist/development/hooks/useProjectUserRoles.js.map +1 -0
  37. package/dist/development/index.cjs +25 -0
  38. package/dist/development/index.cjs.map +1 -0
  39. package/dist/development/index.js +25 -0
  40. package/dist/development/index.js.map +1 -0
  41. package/dist/development/internal/contexts.cjs +13 -0
  42. package/dist/development/internal/contexts.cjs.map +1 -0
  43. package/dist/development/internal/contexts.js +13 -0
  44. package/dist/development/internal/contexts.js.map +1 -0
  45. package/dist/development/internal/hooks/useFetchMe.cjs +32 -0
  46. package/dist/development/internal/hooks/useFetchMe.cjs.map +1 -0
  47. package/dist/development/internal/hooks/useFetchMe.js +15 -0
  48. package/dist/development/internal/hooks/useFetchMe.js.map +1 -0
  49. package/dist/development/internal/hooks/useLogoutInternal.cjs +35 -0
  50. package/dist/development/internal/hooks/useLogoutInternal.cjs.map +1 -0
  51. package/dist/development/internal/hooks/useLogoutInternal.js +35 -0
  52. package/dist/development/internal/hooks/useLogoutInternal.js.map +1 -0
  53. package/dist/development/internal/hooks/useSignOut.cjs +30 -0
  54. package/dist/development/internal/hooks/useSignOut.cjs.map +1 -0
  55. package/dist/development/internal/hooks/useSignOut.js +13 -0
  56. package/dist/development/internal/hooks/useSignOut.js.map +1 -0
  57. package/dist/production/components/HasRole.cjs +24 -0
  58. package/dist/production/components/HasRole.cjs.map +1 -0
  59. package/dist/production/components/HasRole.js +24 -0
  60. package/dist/production/components/HasRole.js.map +1 -0
  61. package/dist/production/components/IdentityProvider.cjs +27 -0
  62. package/dist/production/components/IdentityProvider.cjs.map +1 -0
  63. package/dist/production/components/IdentityProvider.js +27 -0
  64. package/dist/production/components/IdentityProvider.js.map +1 -0
  65. package/dist/production/components/IdentityState.cjs +9 -0
  66. package/dist/production/components/IdentityState.cjs.map +1 -0
  67. package/dist/production/components/IdentityState.js +9 -0
  68. package/dist/production/components/IdentityState.js.map +1 -0
  69. package/dist/production/components/LogoutTrigger.cjs +12 -0
  70. package/dist/production/components/LogoutTrigger.cjs.map +1 -0
  71. package/dist/production/components/LogoutTrigger.js +12 -0
  72. package/dist/production/components/LogoutTrigger.js.map +1 -0
  73. package/dist/production/environment/IdentityEnvironmentExtension.cjs +13 -0
  74. package/dist/production/environment/IdentityEnvironmentExtension.cjs.map +1 -0
  75. package/dist/production/environment/IdentityEnvironmentExtension.js +13 -0
  76. package/dist/production/environment/IdentityEnvironmentExtension.js.map +1 -0
  77. package/dist/production/environment/ProjectEnvironmentExtension.cjs +13 -0
  78. package/dist/production/environment/ProjectEnvironmentExtension.cjs.map +1 -0
  79. package/dist/production/environment/ProjectEnvironmentExtension.js +13 -0
  80. package/dist/production/environment/ProjectEnvironmentExtension.js.map +1 -0
  81. package/dist/production/hooks/useFetchIdentity.cjs +51 -0
  82. package/dist/production/hooks/useFetchIdentity.cjs.map +1 -0
  83. package/dist/production/hooks/useFetchIdentity.js +51 -0
  84. package/dist/production/hooks/useFetchIdentity.js.map +1 -0
  85. package/dist/production/hooks/useLogout.cjs +10 -0
  86. package/dist/production/hooks/useLogout.cjs.map +1 -0
  87. package/dist/production/hooks/useLogout.js +10 -0
  88. package/dist/production/hooks/useLogout.js.map +1 -0
  89. package/dist/production/hooks/useProjectUserRoles.cjs +21 -0
  90. package/dist/production/hooks/useProjectUserRoles.cjs.map +1 -0
  91. package/dist/production/hooks/useProjectUserRoles.js +21 -0
  92. package/dist/production/hooks/useProjectUserRoles.js.map +1 -0
  93. package/dist/production/index.cjs +25 -0
  94. package/dist/production/index.cjs.map +1 -0
  95. package/dist/production/index.js +25 -0
  96. package/dist/production/index.js.map +1 -0
  97. package/dist/production/internal/contexts.cjs +13 -0
  98. package/dist/production/internal/contexts.cjs.map +1 -0
  99. package/dist/production/internal/contexts.js +13 -0
  100. package/dist/production/internal/contexts.js.map +1 -0
  101. package/dist/production/internal/hooks/useFetchMe.cjs +32 -0
  102. package/dist/production/internal/hooks/useFetchMe.cjs.map +1 -0
  103. package/dist/production/internal/hooks/useFetchMe.js +15 -0
  104. package/dist/production/internal/hooks/useFetchMe.js.map +1 -0
  105. package/dist/production/internal/hooks/useLogoutInternal.cjs +35 -0
  106. package/dist/production/internal/hooks/useLogoutInternal.cjs.map +1 -0
  107. package/dist/production/internal/hooks/useLogoutInternal.js +35 -0
  108. package/dist/production/internal/hooks/useLogoutInternal.js.map +1 -0
  109. package/dist/production/internal/hooks/useSignOut.cjs +30 -0
  110. package/dist/production/internal/hooks/useSignOut.cjs.map +1 -0
  111. package/dist/production/internal/hooks/useSignOut.js +13 -0
  112. package/dist/production/internal/hooks/useSignOut.js.map +1 -0
  113. package/dist/types/components/HasRole.d.ts +11 -0
  114. package/dist/types/components/HasRole.d.ts.map +1 -0
  115. package/dist/types/components/IdentityProvider.d.ts +6 -0
  116. package/dist/types/components/IdentityProvider.d.ts.map +1 -0
  117. package/dist/types/components/IdentityState.d.ts +8 -0
  118. package/dist/types/components/IdentityState.d.ts.map +1 -0
  119. package/dist/types/components/LogoutTrigger.d.ts +5 -0
  120. package/dist/types/components/LogoutTrigger.d.ts.map +1 -0
  121. package/dist/types/components/index.d.ts +5 -0
  122. package/dist/types/components/index.d.ts.map +1 -0
  123. package/dist/types/environment/IdentityEnvironmentExtension.d.ts +6 -0
  124. package/dist/types/environment/IdentityEnvironmentExtension.d.ts.map +1 -0
  125. package/dist/types/environment/ProjectEnvironmentExtension.d.ts +5 -0
  126. package/dist/types/environment/ProjectEnvironmentExtension.d.ts.map +1 -0
  127. package/dist/types/environment/index.d.ts +3 -0
  128. package/dist/types/environment/index.d.ts.map +1 -0
  129. package/dist/types/hooks/index.d.ts +5 -0
  130. package/dist/types/hooks/index.d.ts.map +1 -0
  131. package/dist/types/hooks/useFetchIdentity.d.ts +6 -0
  132. package/dist/types/hooks/useFetchIdentity.d.ts.map +1 -0
  133. package/dist/types/hooks/useLogout.d.ts +4 -0
  134. package/dist/types/hooks/useLogout.d.ts.map +1 -0
  135. package/dist/types/hooks/useProjectUserRoles.d.ts +3 -0
  136. package/dist/types/hooks/useProjectUserRoles.d.ts.map +1 -0
  137. package/dist/types/index.d.ts +5 -0
  138. package/dist/types/index.d.ts.map +1 -0
  139. package/dist/types/internal/contexts.d.ts +7 -0
  140. package/dist/types/internal/contexts.d.ts.map +1 -0
  141. package/dist/types/internal/hooks/useFetchMe.d.ts +94 -0
  142. package/dist/types/internal/hooks/useFetchMe.d.ts.map +1 -0
  143. package/dist/types/internal/hooks/useLogoutInternal.d.ts +4 -0
  144. package/dist/types/internal/hooks/useLogoutInternal.d.ts.map +1 -0
  145. package/dist/types/internal/hooks/useSignOut.d.ts +26 -0
  146. package/dist/types/internal/hooks/useSignOut.d.ts.map +1 -0
  147. package/dist/types/tsconfig.tsbuildinfo +1 -0
  148. package/dist/types/types/Identity.d.ts +19 -0
  149. package/dist/types/types/Identity.d.ts.map +1 -0
  150. package/dist/types/types/IdentityMethods.d.ts +5 -0
  151. package/dist/types/types/IdentityMethods.d.ts.map +1 -0
  152. package/dist/types/types/IdentityStateValue.d.ts +2 -0
  153. package/dist/types/types/IdentityStateValue.d.ts.map +1 -0
  154. package/dist/types/types/index.d.ts +4 -0
  155. package/dist/types/types/index.d.ts.map +1 -0
  156. package/package.json +58 -0
  157. package/src/components/HasRole.tsx +33 -0
  158. package/src/components/IdentityProvider.tsx +40 -0
  159. package/src/components/IdentityState.tsx +14 -0
  160. package/src/components/LogoutTrigger.tsx +10 -0
  161. package/src/components/index.ts +4 -0
  162. package/src/environment/IdentityEnvironmentExtension.ts +12 -0
  163. package/src/environment/ProjectEnvironmentExtension.tsx +10 -0
  164. package/src/environment/index.ts +2 -0
  165. package/src/hooks/index.ts +8 -0
  166. package/src/hooks/useFetchIdentity.ts +54 -0
  167. package/src/hooks/useLogout.ts +7 -0
  168. package/src/hooks/useProjectUserRoles.tsx +21 -0
  169. package/src/index.ts +4 -0
  170. package/src/internal/contexts.ts +8 -0
  171. package/src/internal/hooks/useFetchMe.ts +21 -0
  172. package/src/internal/hooks/useLogoutInternal.ts +35 -0
  173. package/src/internal/hooks/useSignOut.ts +13 -0
  174. package/src/tsconfig.json +12 -0
  175. package/src/types/Identity.ts +20 -0
  176. package/src/types/IdentityMethods.ts +4 -0
  177. package/src/types/IdentityStateValue.ts +6 -0
  178. package/src/types/index.ts +3 -0
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@contember/react-identity",
3
+ "license": "Apache-2.0",
4
+ "version": "1.3.0-alpha.14",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "./dist/production/index.js",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/types/index.d.ts",
12
+ "development": "./dist/development/index.js",
13
+ "production": "./dist/production/index.js",
14
+ "default": "./dist/production/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/types/index.d.ts",
18
+ "development": "./dist/development/index.cjs",
19
+ "production": "./dist/production/index.cjs",
20
+ "default": "./dist/production/index.cjs"
21
+ }
22
+ }
23
+ },
24
+ "files": [
25
+ "dist/",
26
+ "src/"
27
+ ],
28
+ "typings": "./dist/types/index.d.ts",
29
+ "scripts": {
30
+ "build": "yarn build:js:dev && yarn build:js:prod",
31
+ "build:js:dev": "vite build --mode development",
32
+ "build:js:prod": "vite build --mode production",
33
+ "ae:build": "api-extractor run --local",
34
+ "ae:test": "api-extractor run",
35
+ "test": "vitest"
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/contember/interface.git",
40
+ "directory": "packages/react-identity"
41
+ },
42
+ "dependencies": {
43
+ "@contember/react-binding": "1.3.0-alpha.14",
44
+ "@contember/react-client": "1.3.0-alpha.14",
45
+ "@contember/react-client-tenant": "1.3.0-alpha.14",
46
+ "@contember/react-utils": "1.3.0-alpha.14",
47
+ "@radix-ui/react-slot": "^1.0.2"
48
+ },
49
+ "peerDependencies": {
50
+ "react": "^17 || ^18",
51
+ "react-dom": "^17 || ^18"
52
+ },
53
+ "devDependencies": {
54
+ "react": "^18.2.0",
55
+ "react-dom": "^18.2.0"
56
+ },
57
+ "stableVersion": "0.0.0"
58
+ }
@@ -0,0 +1,33 @@
1
+ import { Component } from '@contember/react-binding'
2
+ import { ReactNode } from 'react'
3
+ import { useProjectUserRoles } from '../hooks'
4
+ import { identityEnvironmentExtension, projectEnvironmentExtension } from '../environment'
5
+
6
+ export type RoleCondition = string | ((roles: Set<string>) => boolean)
7
+
8
+ export interface HasRoleProps {
9
+ children?: ReactNode
10
+ role: RoleCondition
11
+ }
12
+
13
+ /**
14
+ * @group Logic Components
15
+ */
16
+ export const HasRole = Component<HasRoleProps>(({ children, role }) => {
17
+ const projectRoles = useProjectUserRoles()
18
+
19
+ return evaluateCondition(role, projectRoles) ? <>{children}</> : null
20
+ }, ({ children, role }, env) => {
21
+ const identity = env.getExtension(identityEnvironmentExtension).identity
22
+ const project = env.getExtension(projectEnvironmentExtension).slug
23
+ const projectRoles = new Set(identity?.projects.find(it => it.slug === project)?.roles ?? [])
24
+
25
+ return evaluateCondition(role, projectRoles) ? <>{children}</> : null
26
+ })
27
+
28
+ const evaluateCondition = (condition: RoleCondition, roles: Set<string>) => {
29
+ if (typeof condition === 'string') {
30
+ return roles.has(condition)
31
+ }
32
+ return condition(roles)
33
+ }
@@ -0,0 +1,40 @@
1
+ import { useSessionToken } from '@contember/react-client'
2
+ import { ReactNode, useEffect } from 'react'
3
+ import { EnvironmentExtensionProvider } from '@contember/react-binding'
4
+ import { useFetchIdentity } from '../hooks'
5
+ import { IdentityContext, IdentityMethodsContext, IdentityStateContext } from '../internal/contexts'
6
+ import { identityEnvironmentExtension } from '../environment/IdentityEnvironmentExtension'
7
+
8
+
9
+ export interface IdentityProviderProps {
10
+ children: ReactNode
11
+ }
12
+
13
+ export const IdentityProvider: React.FC<IdentityProviderProps> = ({ children }) => {
14
+ const sessionToken = useSessionToken()
15
+ const [{ identity, state }, methods] = useFetchIdentity()
16
+
17
+ const { refreshIdentity, clearIdentity } = methods
18
+ useEffect(
19
+ () => {
20
+ if (sessionToken !== undefined) {
21
+ refreshIdentity()
22
+ } else {
23
+ clearIdentity()
24
+ }
25
+ },
26
+ [sessionToken, refreshIdentity, clearIdentity],
27
+ )
28
+
29
+ return (
30
+ <IdentityStateContext.Provider value={state}>
31
+ <IdentityContext.Provider value={identity}>
32
+ <IdentityMethodsContext.Provider value={methods}>
33
+ <EnvironmentExtensionProvider extension={identityEnvironmentExtension} state={identity ?? null}>
34
+ {children}
35
+ </EnvironmentExtensionProvider>
36
+ </IdentityMethodsContext.Provider>
37
+ </IdentityContext.Provider>
38
+ </IdentityStateContext.Provider>
39
+ )
40
+ }
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from 'react'
2
+ import { IdentityStateValue } from '../types'
3
+ import { useIdentityState } from '../internal/contexts'
4
+
5
+ export interface IdentityStateProps {
6
+ state: IdentityStateValue | IdentityStateValue[]
7
+ children: ReactNode
8
+ }
9
+
10
+ export const IdentityState = ({ state, children }: IdentityStateProps) => {
11
+ const currentState = useIdentityState()
12
+
13
+ return state === currentState || (Array.isArray(state) && state.includes(currentState)) ? children : null
14
+ }
@@ -0,0 +1,10 @@
1
+ import { ReactNode, useCallback } from 'react'
2
+ import { Slot } from '@radix-ui/react-slot'
3
+ import { useLogout } from '../hooks'
4
+
5
+ export const LogoutTrigger = ({ children }: {
6
+ children: ReactNode
7
+ }) => {
8
+ const logout = useLogout()
9
+ return <Slot onClick={useCallback(() => logout(), [logout])}>{children}</Slot>
10
+ }
@@ -0,0 +1,4 @@
1
+ export * from './HasRole'
2
+ export * from './IdentityProvider'
3
+ export * from './IdentityState'
4
+ export * from './LogoutTrigger'
@@ -0,0 +1,12 @@
1
+ import { BindingError, Environment } from '@contember/react-binding'
2
+ import { Identity } from '../types'
3
+
4
+ export const identityEnvironmentExtension = Environment.createExtension((state: Identity | null | undefined) => {
5
+ if (state === undefined) {
6
+ throw new BindingError('Environment does not contain identity state.')
7
+ }
8
+
9
+ return {
10
+ identity: state ?? undefined,
11
+ }
12
+ })
@@ -0,0 +1,10 @@
1
+ import { BindingError, Environment } from '@contember/react-binding'
2
+
3
+ export const projectEnvironmentExtension = Environment.createExtension((slug: string | null | undefined) => {
4
+ if (slug === undefined) {
5
+ throw new BindingError('Environment does not contain project slug state.')
6
+ }
7
+ return {
8
+ slug: slug ?? undefined,
9
+ }
10
+ })
@@ -0,0 +1,2 @@
1
+ export * from './IdentityEnvironmentExtension'
2
+ export * from './ProjectEnvironmentExtension'
@@ -0,0 +1,8 @@
1
+ export * from './useLogout'
2
+ export * from './useFetchIdentity'
3
+ export * from './useProjectUserRoles'
4
+ export {
5
+ useIdentityMethods,
6
+ useIdentity,
7
+ useIdentityState,
8
+ } from '../internal/contexts'
@@ -0,0 +1,54 @@
1
+ import { useCallback, useMemo, useState } from 'react'
2
+ import { Identity, IdentityMethods, IdentityStateValue } from '../types'
3
+ import { useSessionToken } from '@contember/react-client'
4
+ import { useFetchMe } from '../internal/hooks/useFetchMe'
5
+ import { useLogoutInternal } from '../internal/hooks/useLogoutInternal'
6
+
7
+ export const useFetchIdentity = (): [{ state: IdentityStateValue, identity: Identity | undefined }, IdentityMethods] => {
8
+ const sessionToken = useSessionToken()
9
+ const fetchMe = useFetchMe()
10
+
11
+ const [identityState, setIdentityState] = useState<IdentityStateValue>(sessionToken ? 'loading' : 'none')
12
+ const [identity, setIdentity] = useState<Identity | undefined>()
13
+
14
+ const clearIdentity = useCallback(() => setIdentityState('cleared'), [])
15
+ const logout = useLogoutInternal(clearIdentity)
16
+
17
+ const fetch = useCallback(async () => {
18
+ setIdentityState('loading')
19
+ try {
20
+ const response = await fetchMe()
21
+ const person = response.person
22
+ const projects = response.projects
23
+ const permissions = response.permissions ?? { canCreateProject: false }
24
+
25
+ setIdentityState('success')
26
+ setIdentity({
27
+ id: response.id,
28
+ person: person ?? undefined,
29
+ projects: projects.map(it => ({
30
+ name: it.project.name,
31
+ slug: it.project.slug,
32
+ roles: it.memberships.map(it => it.role),
33
+ })),
34
+ permissions,
35
+ })
36
+ } catch (e) {
37
+ console.error(e)
38
+ if (typeof e === 'object' && e !== null && 'status' in e && (e as { status?: unknown }).status === 401) {
39
+ logout({ noRedirect: true })
40
+ setIdentityState('cleared')
41
+ } else {
42
+ setIdentityState('failed')
43
+ }
44
+ }
45
+ }, [fetchMe, logout])
46
+
47
+ return [
48
+ { state: identityState, identity },
49
+ useMemo((): IdentityMethods => ({
50
+ clearIdentity,
51
+ refreshIdentity: fetch,
52
+ }), [clearIdentity, fetch]),
53
+ ]
54
+ }
@@ -0,0 +1,7 @@
1
+ import { useIdentityMethods } from '../internal/contexts'
2
+ import { useLogoutInternal } from '../internal/hooks/useLogoutInternal'
3
+
4
+ export const useLogout = () => {
5
+ const { clearIdentity } = useIdentityMethods()
6
+ return useLogoutInternal(clearIdentity)
7
+ }
@@ -0,0 +1,21 @@
1
+ import { useMemo } from 'react'
2
+ import { useProjectSlug } from '@contember/react-client'
3
+ import { useIdentity } from '../internal/contexts'
4
+
5
+ export type ProjectUserRoles = Set<string>
6
+
7
+ export const useProjectUserRoles = (): ProjectUserRoles => {
8
+ const identity = useIdentity()
9
+ const projectSlug = useProjectSlug()
10
+ return useMemo(() => {
11
+ if (!projectSlug) {
12
+ return new Set()
13
+ }
14
+ const targetProject = identity?.projects.find(project => project.slug === projectSlug)
15
+ if (targetProject === undefined) {
16
+ return new Set()
17
+ }
18
+
19
+ return new Set(targetProject.roles)
20
+ }, [identity?.projects, projectSlug])
21
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './types'
2
+ export * from './components'
3
+ export * from './hooks'
4
+ export * from './environment'
@@ -0,0 +1,8 @@
1
+ import { createContext, createRequiredContext } from '@contember/react-utils'
2
+ import { IdentityMethods } from '../types/IdentityMethods'
3
+ import { Identity } from '../types/Identity'
4
+ import { IdentityStateValue } from '../types/IdentityStateValue'
5
+
6
+ export const [IdentityContext, useIdentity] = createContext<Identity | undefined>('IdentityContext', undefined)
7
+ export const [IdentityMethodsContext, useIdentityMethods] = createRequiredContext<IdentityMethods>('IdentityMethodsContext')
8
+ export const [IdentityStateContext, useIdentityState] = createRequiredContext<IdentityStateValue>('IdentityStateContext')
@@ -0,0 +1,21 @@
1
+ import * as TenantApi from '@contember/react-client-tenant'
2
+ import { useCallback } from 'react'
3
+
4
+ const identityFragment = TenantApi
5
+ .identity$$
6
+ .person(TenantApi.person$$)
7
+ .projects(TenantApi
8
+ .identityProjectRelation$
9
+ .project(TenantApi.project$$)
10
+ .memberships(TenantApi.membership$$.variables(TenantApi.variableEntry$$)),
11
+ )
12
+ .permissions(TenantApi.identityGlobalPermissions$$)
13
+
14
+ export type FetchedIdentity = TenantApi.ModelType<typeof identityFragment>
15
+
16
+ export const useFetchMe = () => {
17
+ const executor = TenantApi.useTenantApi()
18
+ return useCallback(async () => {
19
+ return (await executor(TenantApi.query$.me(identityFragment))).me
20
+ }, [executor])
21
+ }
@@ -0,0 +1,35 @@
1
+ import { useSetSessionToken } from '@contember/react-client'
2
+ import { useCallback } from 'react'
3
+ import { useSignOut } from './useSignOut'
4
+
5
+ export const useLogoutInternal = (clearIdentity?: () => void) => {
6
+ const tenantLogout = useSignOut()
7
+ const setSessionToken = useSetSessionToken()
8
+
9
+ return useCallback(
10
+ async ({ noRedirect = false }: { noRedirect?: boolean } = {}) => {
11
+ if (navigator.credentials && navigator.credentials.preventSilentAccess) {
12
+ try {
13
+ await navigator.credentials.preventSilentAccess()
14
+ } catch {
15
+ // actually, not implemented in safari:
16
+ // https://github.com/WebKit/WebKit/blob/414f4e45b0e82bbfcee783d08a9642be1afa8f72/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.cpp#L132
17
+ }
18
+ }
19
+ clearIdentity?.()
20
+ setSessionToken(undefined)
21
+ try {
22
+ const response = await tenantLogout()
23
+ if (!response?.ok) {
24
+ console.warn(response?.error)
25
+ }
26
+ } catch (e) {
27
+ console.warn(e)
28
+ }
29
+ if (!noRedirect) {
30
+ window.location.href = '/' // todo better redirect?
31
+ }
32
+ },
33
+ [clearIdentity, setSessionToken, tenantLogout],
34
+ )
35
+ }
@@ -0,0 +1,13 @@
1
+ import * as TenantApi from '@contember/react-client-tenant'
2
+ import { useCallback } from 'react'
3
+
4
+ const signOutFragment = TenantApi.signOutResponse$$.error(TenantApi.signOutError$$)
5
+
6
+ export type SignOutResult = TenantApi.ModelType<typeof signOutFragment>
7
+
8
+ export const useSignOut = () => {
9
+ const api = TenantApi.useTenantApi()
10
+ return useCallback(async () => {
11
+ return (await api(TenantApi.mutation$.signOut(signOutFragment))).signOut
12
+ }, [api])
13
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../../tsconfig.settings.json",
3
+ "compilerOptions": {
4
+ "outDir": "../dist/types"
5
+ },
6
+ "references": [
7
+ { "path": "../../react-binding/src" },
8
+ { "path": "../../react-client/src" },
9
+ { "path": "../../react-client-tenant/src" },
10
+ { "path": "../../react-utils/src" },
11
+ ]
12
+ }
@@ -0,0 +1,20 @@
1
+ export interface Identity {
2
+ readonly id: string
3
+ readonly person?: Person
4
+ readonly projects: IdentityProject[]
5
+ readonly permissions: {
6
+ readonly canCreateProject: boolean
7
+ }
8
+ }
9
+
10
+ export interface Person {
11
+ readonly id: string
12
+ readonly email?: string
13
+ readonly otpEnabled: boolean
14
+ }
15
+
16
+ export interface IdentityProject {
17
+ readonly slug: string
18
+ readonly name: string
19
+ readonly roles: readonly string[]
20
+ }
@@ -0,0 +1,4 @@
1
+ export interface IdentityMethods {
2
+ clearIdentity: () => void
3
+ refreshIdentity: () => Promise<void>
4
+ }
@@ -0,0 +1,6 @@
1
+ export type IdentityStateValue =
2
+ | 'none'
3
+ | 'loading'
4
+ | 'failed'
5
+ | 'cleared'
6
+ | 'success'
@@ -0,0 +1,3 @@
1
+ export * from './IdentityMethods'
2
+ export * from './IdentityStateValue'
3
+ export * from './Identity'