@rpcbase/client 0.56.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auth/AccountsList/AccountListItem.js +67 -0
- package/auth/AccountsList/account-list-item.scss +5 -0
- package/auth/AccountsList/index.js +19 -0
- package/auth/SignOut/index.js +73 -26
- package/auth/SignOut/sign-out.scss +34 -0
- package/auth/index.js +19 -1
- package/hashState.js +10 -3
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import assert from "assert"
|
|
3
|
+
import {useTranslation} from "react-i18next"
|
|
4
|
+
import page from "page"
|
|
5
|
+
|
|
6
|
+
import Avatar from "ui/avatars/Avatar"
|
|
7
|
+
import getInitials from "ui/avatars/Avatar/getInitials"
|
|
8
|
+
|
|
9
|
+
import "./account-list-item.scss"
|
|
10
|
+
|
|
11
|
+
const getAvatarText = (user) => {
|
|
12
|
+
if (user.initials) return user.initials
|
|
13
|
+
|
|
14
|
+
const fullName = `${user.first_name || ""} ${user.last_name || ""}`
|
|
15
|
+
let initials = getInitials(fullName)
|
|
16
|
+
|
|
17
|
+
if (!initials) initials = "?"
|
|
18
|
+
|
|
19
|
+
return initials
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const getTenantName = (tenant) => {
|
|
24
|
+
if (tenant.short_name) return tenant.short_name
|
|
25
|
+
else if (tenant.name) return tenant.name
|
|
26
|
+
else return tenant.slug
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getUserName = (user) => {
|
|
30
|
+
let name = ""
|
|
31
|
+
|
|
32
|
+
if (user.first_name) {
|
|
33
|
+
name += user.first_name
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (user.last_name) {
|
|
37
|
+
name += ` ${user.last_name}`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!name && user.initials) {
|
|
41
|
+
name += user.initials
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!name) {
|
|
45
|
+
name = user.email
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return name
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const AccountListItem = ({account, onClick, avatarProps}) => {
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
key={`acc-${account.user._id}`}
|
|
56
|
+
className="account-list-item d-flex flex-row"
|
|
57
|
+
onClick={() => onClick(account)}
|
|
58
|
+
>
|
|
59
|
+
<div>
|
|
60
|
+
<Avatar className="me-2" size="small" text={getAvatarText(account.user)} color={account.user.avatar_color} {...avatarProps} />
|
|
61
|
+
</div>
|
|
62
|
+
<div style={{wordBreak: "break-all"}}>{getTenantName(account.tenant)} / {getUserName(account.user)}</div>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default AccountListItem
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import AccountListItem from "./AccountListItem"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const AccountsList = ({accounts}) => {
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
{accounts.map((acc) => (
|
|
10
|
+
<AccountListItem
|
|
11
|
+
key={`acc-${acc.user._id}`}
|
|
12
|
+
account={acc}
|
|
13
|
+
/>
|
|
14
|
+
))}
|
|
15
|
+
</>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default AccountsList
|
package/auth/SignOut/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
+
import assert from "assert"
|
|
2
3
|
import {useState, useEffect} from "react"
|
|
3
4
|
import {ActivityIndicator} from "react-native"
|
|
4
5
|
import page from "page"
|
|
@@ -6,49 +7,95 @@ import page from "page"
|
|
|
6
7
|
import post from "../../helpers/post"
|
|
7
8
|
|
|
8
9
|
import {set_is_signed_in, set_uid} from "../index"
|
|
10
|
+
import AccountListItem from "../AccountsList/AccountListItem"
|
|
11
|
+
import Footer from "../Footer"
|
|
12
|
+
|
|
13
|
+
import "./sign-out.scss"
|
|
9
14
|
|
|
10
15
|
// TODO: rts_disconnect
|
|
11
16
|
// TODO: clear cache + db
|
|
12
17
|
|
|
13
18
|
const SignOut = ({
|
|
19
|
+
name,
|
|
14
20
|
onSuccess = () => null
|
|
15
21
|
}) => {
|
|
16
22
|
|
|
17
23
|
const [isSignedOut, setIsSignedOut] = useState(false)
|
|
18
24
|
|
|
25
|
+
const [accounts, setAccounts] = useState([])
|
|
26
|
+
|
|
19
27
|
useEffect(() => {
|
|
20
|
-
|
|
21
|
-
const res = await post("/api/v1/auth/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// TODO: clear DB
|
|
28
|
-
|
|
29
|
-
setIsSignedOut(true)
|
|
30
|
-
onSuccess()
|
|
31
|
-
} else {
|
|
32
|
-
throw new Error("unable to sign out")
|
|
33
|
-
}
|
|
34
|
-
}, 60)
|
|
28
|
+
const load = async() => {
|
|
29
|
+
const res = await post("/api/v1/auth/get_accounts")
|
|
30
|
+
assert(res.status === "ok")
|
|
31
|
+
setAccounts(res.accounts)
|
|
32
|
+
console.log("ACCOUNTS", res.accounts)
|
|
33
|
+
}
|
|
35
34
|
|
|
35
|
+
load()
|
|
36
36
|
}, [])
|
|
37
37
|
|
|
38
|
+
|
|
39
|
+
const signOut = async() => {
|
|
40
|
+
const res = await post("/api/v1/auth/sign_out")
|
|
41
|
+
if (res.status === "ok") {
|
|
42
|
+
set_uid(null)
|
|
43
|
+
set_is_signed_in(false)
|
|
44
|
+
localStorage.clear()
|
|
45
|
+
|
|
46
|
+
// TODO: clear DB
|
|
47
|
+
|
|
48
|
+
setIsSignedOut(true)
|
|
49
|
+
onSuccess()
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error("unable to sign out")
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const onClickAccount = () => {
|
|
57
|
+
console.log("clicked account")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
const onSubmit = () => {
|
|
62
|
+
signOut()
|
|
63
|
+
}
|
|
64
|
+
|
|
38
65
|
return (
|
|
39
66
|
<div id="sign-out-wrapper">
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
67
|
+
{isSignedOut && <div>signed out successfully</div>}
|
|
68
|
+
{accounts?.length > 0 && (<><div className="form-signout text-center px-4 py-4 shadow-lg">
|
|
69
|
+
<div>
|
|
70
|
+
<h1 className="h4 mt-3 mb-3 fw-normal">Sign Out</h1>
|
|
71
|
+
<p className="text-start text-muted">
|
|
72
|
+
Select accounts to sign out of:
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
<ul className="list-group text-start">
|
|
76
|
+
{accounts.map((acc, index) => {
|
|
77
|
+
const id = `acc-${acc.user_id}-${index}`
|
|
78
|
+
return (
|
|
79
|
+
<li key={id} className="list-group-item">
|
|
80
|
+
<input className="form-check-input me-3" type="checkbox" value="" id={id} />
|
|
81
|
+
<label className="form-check-label stretched-link" for={id}>
|
|
82
|
+
<AccountListItem
|
|
83
|
+
account={acc}
|
|
84
|
+
onClick={onClickAccount}
|
|
85
|
+
/>
|
|
86
|
+
</label>
|
|
87
|
+
</li>
|
|
88
|
+
)
|
|
89
|
+
})}
|
|
90
|
+
</ul>
|
|
91
|
+
|
|
92
|
+
<button className="mt-4 mb-3 w-100 btn btn-lg btn-primary" type="submit" onClick={onSubmit}>Sign Out</button>
|
|
93
|
+
|
|
50
94
|
</div>
|
|
51
|
-
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<Footer name={name} />
|
|
98
|
+
</>)}
|
|
52
99
|
</div>
|
|
53
100
|
)
|
|
54
101
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@import "helpers";
|
|
2
|
+
|
|
3
|
+
#sign-out-wrapper {
|
|
4
|
+
height: 100%;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: center;
|
|
8
|
+
padding-top: 40px;
|
|
9
|
+
padding-bottom: 40px;
|
|
10
|
+
// background-color: var(--bs-secondary);
|
|
11
|
+
background-color: $gray-500;
|
|
12
|
+
|
|
13
|
+
footer {
|
|
14
|
+
color: $light !important;
|
|
15
|
+
border-top: none !important;
|
|
16
|
+
padding-top: 0 !important;
|
|
17
|
+
margin-bottom: 0 !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
.form-signout {
|
|
22
|
+
width: 100%;
|
|
23
|
+
max-width: 380px;
|
|
24
|
+
margin: auto;
|
|
25
|
+
background-color: $light;
|
|
26
|
+
border-radius: 22px;
|
|
27
|
+
// border: 1px solid $gray-600;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.form-signout .checkbox {
|
|
31
|
+
font-weight: 400;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
package/auth/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
import page from "page"
|
|
3
3
|
import debug from "debug"
|
|
4
|
+
import isHexadecimal from "validator/lib/isHexadecimal"
|
|
4
5
|
|
|
5
6
|
import {disconnect as rts_disconnect} from "../rts"
|
|
6
7
|
import post from "../helpers/post"
|
|
@@ -18,8 +19,25 @@ let __tenant_id = typeof localStorage !== "undefined" && localStorage.getItem(LA
|
|
|
18
19
|
let __user_id = typeof localStorage !== "undefined" && __tenant_id && localStorage.getItem(uid_storage_key(__tenant_id))
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
const get_querystring_auth_id = () => {
|
|
23
|
+
const url = new URL(window.location.href)
|
|
24
|
+
const val = url.searchParams.get("auth_id")
|
|
25
|
+
if (!val) return null
|
|
26
|
+
|
|
27
|
+
if (isHexadecimal(val) && val.length === 24) return val
|
|
28
|
+
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
21
33
|
const run_session_check = async() => {
|
|
22
|
-
const
|
|
34
|
+
const auth_user_id = get_querystring_auth_id()
|
|
35
|
+
|
|
36
|
+
if (auth_user_id) {
|
|
37
|
+
log("check_session with auth user_id", auth_user_id)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const res = await post("/api/v1/auth/check_session", {auth_user_id})
|
|
23
41
|
|
|
24
42
|
log("check_session response", res)
|
|
25
43
|
|
package/hashState.js
CHANGED
|
@@ -5,8 +5,8 @@ import _isNil from "lodash/isNil"
|
|
|
5
5
|
import _omitBy from "lodash/omitBy"
|
|
6
6
|
import isEqual from "fast-deep-equal"
|
|
7
7
|
|
|
8
|
-
import {PAGE_NAVIGATION} from "config/events"
|
|
9
8
|
|
|
9
|
+
const PAGE_NAVIGATION_EVENT = "RB_PAGE_NAVIGATION"
|
|
10
10
|
|
|
11
11
|
const EMPTY_STATE_TOKEN = "N4XyA" // lz-string encoded empty state ''
|
|
12
12
|
|
|
@@ -91,9 +91,9 @@ export const HashStateProvider = ({children}) => {
|
|
|
91
91
|
setHashState(newState)
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
document.body.addEventListener(
|
|
94
|
+
document.body.addEventListener(PAGE_NAVIGATION_EVENT, onChange)
|
|
95
95
|
|
|
96
|
-
return () => document.body.removeEventListener(
|
|
96
|
+
return () => document.body.removeEventListener(PAGE_NAVIGATION_EVENT, onChange)
|
|
97
97
|
}, [hashState, setHashState])
|
|
98
98
|
|
|
99
99
|
useEffect(() => {
|
|
@@ -139,3 +139,10 @@ export const HashStateProvider = ({children}) => {
|
|
|
139
139
|
</HashContext.Provider>
|
|
140
140
|
)
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
export const hashStateMiddleware = (context, next) => {
|
|
145
|
+
next()
|
|
146
|
+
const ev = new CustomEvent(PAGE_NAVIGATION_EVENT, {detail: {context}})
|
|
147
|
+
document.body.dispatchEvent(ev)
|
|
148
|
+
}
|