@rpcbase/client 0.53.0 → 0.55.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/AppProvider/index.js +29 -12
- package/auth/SignIn/index.js +7 -3
- package/auth/get_tenant_id.js +11 -0
- package/auth/index.js +34 -8
- package/package.json +1 -1
- package/rpc_post.js +6 -1
- package/rts/cacheStorage/index.jest.js +18 -0
- package/rts/cacheStorage/{native.js → index.native.js} +1 -1
- package/rts/cacheStorage/{web.js → index.web.js} +1 -1
- package/rts/getUseQuery.js +2 -2
- package/rts/index.js +31 -8
- package/rts/cacheStorage/index.js +0 -12
package/AppProvider/index.js
CHANGED
|
@@ -10,24 +10,41 @@ import {flagValues} from "config/flags"
|
|
|
10
10
|
|
|
11
11
|
import {POSTHOG_KEY} from "env"
|
|
12
12
|
|
|
13
|
-
const AppProvider = ({children, ...props}) => {
|
|
14
13
|
|
|
14
|
+
const AnalyticsWrapper = ({children, ...props}) => {
|
|
15
|
+
|
|
16
|
+
const {hostname} = window.location
|
|
17
|
+
if (__DEV__ || hostname === "localhost" || hostname.endsWith(".local")) {
|
|
18
|
+
return (
|
|
19
|
+
<>{children}</>
|
|
20
|
+
)
|
|
21
|
+
} else {
|
|
22
|
+
return (
|
|
23
|
+
<PostHogProvider
|
|
24
|
+
apiKey={POSTHOG_KEY}
|
|
25
|
+
options={{
|
|
26
|
+
api_host: "https://eu.posthog.com",
|
|
27
|
+
// TODO: this doesn't work
|
|
28
|
+
bootstrap: {
|
|
29
|
+
featureFlags: flagValues,
|
|
30
|
+
},
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</PostHogProvider>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
const AppProvider = ({children, ...props}) => {
|
|
15
41
|
|
|
16
42
|
return (
|
|
17
|
-
<
|
|
18
|
-
apiKey={POSTHOG_KEY}
|
|
19
|
-
options={{
|
|
20
|
-
api_host: "https://eu.posthog.com",
|
|
21
|
-
// TODO: this doesn't work
|
|
22
|
-
bootstrap: {
|
|
23
|
-
featureFlags: flagValues,
|
|
24
|
-
},
|
|
25
|
-
}}
|
|
26
|
-
>
|
|
43
|
+
<AnalyticsWrapper>
|
|
27
44
|
<HashStateProvider>
|
|
28
45
|
{children}
|
|
29
46
|
</HashStateProvider>
|
|
30
|
-
</
|
|
47
|
+
</AnalyticsWrapper>
|
|
31
48
|
)
|
|
32
49
|
|
|
33
50
|
}
|
package/auth/SignIn/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 {useSearchParam} from "react-use"
|
|
4
5
|
import isEmail from "validator/lib/isEmail"
|
|
@@ -8,7 +9,7 @@ import debug from "debug"
|
|
|
8
9
|
import post from "../../helpers/post"
|
|
9
10
|
import {reconnect as rts_reconnect} from "../../rts"
|
|
10
11
|
|
|
11
|
-
import {set_is_signed_in, set_uid} from "../index"
|
|
12
|
+
import {set_is_signed_in, set_uid, set_tenant_id} from "../index"
|
|
12
13
|
import Footer from "../Footer"
|
|
13
14
|
|
|
14
15
|
import "./sign-in.scss"
|
|
@@ -16,7 +17,6 @@ import "./sign-in.scss"
|
|
|
16
17
|
|
|
17
18
|
const log = debug("rb:auth:signin")
|
|
18
19
|
|
|
19
|
-
|
|
20
20
|
const SIGNIN_WITH_GITHUB = false
|
|
21
21
|
|
|
22
22
|
const SignIn = ({
|
|
@@ -52,7 +52,11 @@ const SignIn = ({
|
|
|
52
52
|
if (res.status === "ok") {
|
|
53
53
|
log("signed in res: ok", res)
|
|
54
54
|
log("redirect to:", redirect || onSuccessRedirect)
|
|
55
|
-
|
|
55
|
+
const {user_id} = res
|
|
56
|
+
assert(res.user_id, "missing user_id")
|
|
57
|
+
|
|
58
|
+
set_uid(user_id)
|
|
59
|
+
set_tenant_id(user_id.slice(0, 8))
|
|
56
60
|
set_is_signed_in(true)
|
|
57
61
|
|
|
58
62
|
// we must now reconnect on the websocket as we now have a new cookie
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import {Platform} from "react-native"
|
|
3
|
+
|
|
4
|
+
import {get_tenant_id as _get_tenant_id} from "./index"
|
|
5
|
+
|
|
6
|
+
const get_tenant_id = Platform.OS === "web" ? _get_tenant_id : () => {
|
|
7
|
+
console.warn("native should not call get_tenant_id, use tenantId from AuthContext")
|
|
8
|
+
return null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default get_tenant_id
|
package/auth/index.js
CHANGED
|
@@ -2,27 +2,50 @@
|
|
|
2
2
|
import page from "page"
|
|
3
3
|
import debug from "debug"
|
|
4
4
|
|
|
5
|
+
import {disconnect as rts_disconnect} from "../rts"
|
|
5
6
|
import post from "../helpers/post"
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
const
|
|
8
|
+
const LAST_TENANT_KEY = "rb.last_tenant_id"
|
|
9
|
+
const uid_storage_key = (tenant_id) => `rb.${tenant_id}.user_id`
|
|
9
10
|
|
|
10
11
|
const log = debug("rb:auth")
|
|
11
12
|
|
|
12
13
|
// TODO: this should be refactored to AuthContext + Provider
|
|
13
14
|
|
|
14
15
|
let __is_authenticated = null
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
let __tenant_id = typeof localStorage !== "undefined" && localStorage.getItem(LAST_TENANT_KEY)
|
|
18
|
+
let __user_id = typeof localStorage !== "undefined" && __tenant_id && localStorage.getItem(uid_storage_key(__tenant_id))
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
const run_session_check = async() => {
|
|
19
22
|
const res = await post("/api/v1/auth/check_session")
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
log("check_session response", res)
|
|
25
|
+
|
|
22
26
|
__is_authenticated = res.is_signed_in
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
// if not authenticated, clear __user_id + __tenant_id and disconnect socket
|
|
30
|
+
if (!__is_authenticated) {
|
|
31
|
+
__user_id = null
|
|
32
|
+
__tenant_id = null
|
|
33
|
+
rts_disconnect()
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
__user_id = res.user_id
|
|
38
|
+
__tenant_id = __user_id.slice(0, 8)
|
|
39
|
+
|
|
40
|
+
// save tenant id
|
|
41
|
+
// TODO: should we be using session storage here ?
|
|
42
|
+
if (__tenant_id) {
|
|
43
|
+
localStorage.setItem(LAST_TENANT_KEY, __tenant_id)
|
|
44
|
+
|
|
45
|
+
// cache user_id in localStorage
|
|
46
|
+
if (__user_id) {
|
|
47
|
+
localStorage.setItem(uid_storage_key(__tenant_id), __user_id)
|
|
48
|
+
}
|
|
26
49
|
}
|
|
27
50
|
}
|
|
28
51
|
|
|
@@ -69,6 +92,9 @@ export const session_restrict = (ctx, next) => {
|
|
|
69
92
|
export const get_uid = () => __user_id
|
|
70
93
|
export const set_uid = (val) => __user_id = val
|
|
71
94
|
|
|
95
|
+
export const get_tenant_id = () => __tenant_id
|
|
96
|
+
export const set_tenant_id = (val) => __tenant_id = val
|
|
97
|
+
|
|
72
98
|
export const set_is_signed_in = (val) => __is_authenticated = val
|
|
73
99
|
|
|
74
100
|
export const is_signed_in = () => __is_authenticated
|
package/package.json
CHANGED
package/rpc_post.js
CHANGED
|
@@ -7,12 +7,15 @@ import _set from "lodash/set"
|
|
|
7
7
|
import get_txn_id from "@rpcbase/std/get_txn_id"
|
|
8
8
|
import {add_local_txn} from "@rpcbase/client/rts"
|
|
9
9
|
|
|
10
|
+
import get_tenant_id from "./auth/get_tenant_id"
|
|
10
11
|
import BASE_URL from "./base_url"
|
|
11
12
|
|
|
13
|
+
const TENANT_ID_HEADER = "rb-tenant-id"
|
|
14
|
+
|
|
12
15
|
const client = axios.create({
|
|
13
16
|
withCredentials: true,
|
|
14
17
|
headers: {
|
|
15
|
-
"Content-Type": "application/json"
|
|
18
|
+
"Content-Type": "application/json",
|
|
16
19
|
},
|
|
17
20
|
})
|
|
18
21
|
|
|
@@ -25,6 +28,8 @@ const rpc_post = async(url, payload, options = {}) => {
|
|
|
25
28
|
assert(txn_id, `unable to find txn_id for request ${url}`)
|
|
26
29
|
add_local_txn(txn_id)
|
|
27
30
|
|
|
31
|
+
options.headers[TENANT_ID_HEADER] = get_tenant_id()
|
|
32
|
+
|
|
28
33
|
const res = await client.post(`${BASE_URL}${url}`, payload, options)
|
|
29
34
|
|
|
30
35
|
if (res.data === "") {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
const getEmptyStorage = () => {
|
|
4
|
+
|
|
5
|
+
const cacheStorage = {
|
|
6
|
+
get: async(key) => {
|
|
7
|
+
},
|
|
8
|
+
set: async(key, obj) => {
|
|
9
|
+
},
|
|
10
|
+
delete: async(key) => {
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return cacheStorage
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export default getEmptyStorage()
|
package/rts/getUseQuery.js
CHANGED
|
@@ -6,12 +6,12 @@ import debug from "debug"
|
|
|
6
6
|
import isEqual from "fast-deep-equal/react"
|
|
7
7
|
import _omit from "lodash/omit"
|
|
8
8
|
|
|
9
|
-
import get_uid from "
|
|
9
|
+
import get_uid from "../auth/get_uid"
|
|
10
10
|
|
|
11
11
|
import cacheStorage from "./cacheStorage"
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
const log = debug("rb:
|
|
14
|
+
const log = debug("rb:useQuery")
|
|
15
15
|
|
|
16
16
|
const getUseQuery = (register_query) => (
|
|
17
17
|
model_name,
|
package/rts/index.js
CHANGED
|
@@ -6,12 +6,16 @@ import _set from "lodash/set"
|
|
|
6
6
|
import debug from "debug"
|
|
7
7
|
|
|
8
8
|
import BASE_URL from "../base_url"
|
|
9
|
+
import {get_tenant_id} from "../auth"
|
|
9
10
|
|
|
10
11
|
import store from "./store"
|
|
11
12
|
import getUseQuery from "./getUseQuery"
|
|
12
13
|
|
|
13
|
-
const log = debug("rb:
|
|
14
|
+
const log = debug("rb:socket")
|
|
14
15
|
|
|
16
|
+
const TENANT_ID_HEADER = "rb-tenant-id"
|
|
17
|
+
|
|
18
|
+
// how many local transaction ids are we keeping, it doesn't really need to be that big
|
|
15
19
|
const MAX_TXN_BUF = 2048
|
|
16
20
|
|
|
17
21
|
let _socket
|
|
@@ -83,13 +87,23 @@ const dispatch_query_payload = (payload) => {
|
|
|
83
87
|
|
|
84
88
|
|
|
85
89
|
export const connect = () => new Promise((resolve) => {
|
|
86
|
-
|
|
90
|
+
const tenant_id = get_tenant_id()
|
|
91
|
+
|
|
92
|
+
if (tenant_id) {
|
|
93
|
+
log("rts client will connect")
|
|
94
|
+
} else {
|
|
95
|
+
log("no tenant_id, rts connect will skip")
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
|
|
88
100
|
_socket = io(BASE_URL, {
|
|
89
101
|
forceNew: true,
|
|
90
102
|
transports: ["websocket", "polling"],
|
|
91
103
|
withCredentials: true,
|
|
92
|
-
|
|
104
|
+
query: {
|
|
105
|
+
[TENANT_ID_HEADER]: tenant_id,
|
|
106
|
+
},
|
|
93
107
|
// https://socket.io/docs/v4/client-options/#reconnection
|
|
94
108
|
reconnection: true,
|
|
95
109
|
reconnectionAttempts: 128,
|
|
@@ -124,14 +138,23 @@ export const connect = () => new Promise((resolve) => {
|
|
|
124
138
|
})
|
|
125
139
|
})
|
|
126
140
|
|
|
141
|
+
|
|
142
|
+
export const disconnect = () => {
|
|
143
|
+
if (_socket) {
|
|
144
|
+
_socket.disconnect()
|
|
145
|
+
_socket = null
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
127
150
|
export const reconnect = () => {
|
|
128
151
|
log("socket will force reconnect")
|
|
129
|
-
_socket?.disconnect()
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
_socket?.connect()
|
|
132
|
-
}, 200)
|
|
133
|
-
}
|
|
134
152
|
|
|
153
|
+
// destroy current socket if exists
|
|
154
|
+
disconnect()
|
|
155
|
+
|
|
156
|
+
connect()
|
|
157
|
+
}
|
|
135
158
|
|
|
136
159
|
// register a query
|
|
137
160
|
export const register_query = (model_name, query, _options, _callback) => {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import {Platform} from "react-native"
|
|
3
|
-
|
|
4
|
-
import getWebStorage from "./web"
|
|
5
|
-
import getNativeStorage from "./native"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// TODO: add support for storage expiration
|
|
9
|
-
|
|
10
|
-
const storage = Platform.OS === "web" ? getWebStorage() : getNativeStorage()
|
|
11
|
-
|
|
12
|
-
export default storage
|