@basictech/react 0.2.0-beta.6 → 0.2.0-beta.8

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.
@@ -79,7 +79,7 @@ type Token = {
79
79
 
80
80
  export const BasicContext = createContext<{
81
81
  unicorn: string,
82
- isLoaded: boolean,
82
+ isAuthReady: boolean,
83
83
  isSignedIn: boolean,
84
84
  user: User | null,
85
85
  signout: () => void,
@@ -90,7 +90,7 @@ export const BasicContext = createContext<{
90
90
  dbStatus: DBStatus
91
91
  }>({
92
92
  unicorn: "🦄",
93
- isLoaded: false,
93
+ isAuthReady: false,
94
94
  isSignedIn: false,
95
95
  user: null,
96
96
  signout: () => { },
@@ -98,7 +98,7 @@ export const BasicContext = createContext<{
98
98
  getToken: () => new Promise(() => { }),
99
99
  getSignInLink: () => "",
100
100
  db: {},
101
- dbStatus: DBStatus.OFFLINE
101
+ dbStatus: DBStatus.LOADING
102
102
  });
103
103
 
104
104
  const EmptyDB: BasicSyncType = {
@@ -140,17 +140,16 @@ type ErrorObject = {
140
140
  }
141
141
 
142
142
  export function BasicProvider({ children, project_id, schema, debug = false }: { children: React.ReactNode, project_id: string, schema: any, debug?: boolean }) {
143
- const [isLoaded, setIsLoaded] = useState(false)
144
- const [isSignedIn, setIsSignedIn] = useState(false)
143
+ const [isAuthReady, setIsAuthReady] = useState(false)
144
+ const [isSignedIn, setIsSignedIn] = useState<boolean>(false)
145
145
  const [token, setToken] = useState<Token | null>(null)
146
- const [authCode, setAuthCode] = useState<string | null>(null)
147
146
  const [user, setUser] = useState<User>({})
148
147
 
149
148
  const [dbStatus, setDbStatus] = useState<DBStatus>(DBStatus.LOADING)
149
+ const [error, setError] = useState<ErrorObject | null>(null)
150
150
 
151
151
  const syncRef = useRef<BasicSync | null>(null);
152
152
 
153
- const [error, setError] = useState<ErrorObject | null>(null)
154
153
 
155
154
  useEffect(() => {
156
155
  function initDb() {
@@ -173,6 +172,7 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
173
172
 
174
173
 
175
174
  if (!syncRef.current) {
175
+ log('Initializing BasicDB')
176
176
  syncRef.current = new BasicSync('basicdb', { schema: schema });
177
177
 
178
178
  // log('db is open', syncRef.current.isOpen())
@@ -180,30 +180,41 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
180
180
  // .then(() => {
181
181
  // log("is open now:", syncRef.current.isOpen())
182
182
  // })
183
-
184
- syncRef.current.handleStatusChange((status: number, url: string) => {
185
- setDbStatus(getSyncStatus(status))
186
- })
187
-
188
- syncRef.current.syncable.getStatus().then((status) => {
189
- log('sync status', getSyncStatus(status))
190
- })
191
183
  }
192
-
193
184
  }
194
185
 
195
186
  initDb()
196
187
  }, []);
197
188
 
189
+ useEffect(() => {
190
+ if (!syncRef.current) {
191
+ return
192
+ }
193
+
194
+ // syncRef.current.handleStatusChange((status: number, url: string) => {
195
+ // setDbStatus(getSyncStatus(status))
196
+ // })
197
+
198
+ syncRef.current.syncable.on('statusChanged', (status: number, url: string) => {
199
+ setDbStatus(getSyncStatus(status))
200
+ })
201
+
202
+ syncRef.current.syncable.getStatus().then((status) => {
203
+ setDbStatus(getSyncStatus(status))
204
+ })
205
+ }, [syncRef.current])
198
206
 
199
- //todo:
200
- //add random state to signin link & verify random state
201
207
 
202
208
  const connectToDb = async () => {
203
-
204
209
  const tok = await getToken()
210
+ if (!tok) {
211
+ log('no token found')
212
+ return
213
+ }
214
+
215
+ log('connecting to db...')
205
216
 
206
- log('connecting to db...', tok.substring(0, 10))
217
+ // TODO: handle if signed out after connect() is already called
207
218
 
208
219
  syncRef.current.connect({ access_token: tok })
209
220
  .catch((e) => {
@@ -220,14 +231,15 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
220
231
  const getSignInLink = () => {
221
232
  log('getting sign in link...')
222
233
 
223
- const randomState = Math.random().toString(36).substring(7);
234
+ const randomState = Math.random().toString(36).substring(6);
235
+ localStorage.setItem('basic_auth_state', randomState)
224
236
 
225
237
  let baseUrl = "https://api.basic.tech/auth/authorize"
226
238
  baseUrl += `?client_id=${project_id}`
227
239
  baseUrl += `&redirect_uri=${encodeURIComponent(window.location.href)}`
228
240
  baseUrl += `&response_type=code`
229
241
  baseUrl += `&scope=openid`
230
- baseUrl += `&state=1234zyx`
242
+ baseUrl += `&state=${randomState}`
231
243
 
232
244
  return baseUrl;
233
245
  }
@@ -244,8 +256,8 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
244
256
  setUser({})
245
257
  setIsSignedIn(false)
246
258
  setToken(null)
247
- setAuthCode(null)
248
259
  document.cookie = `basic_token=; Secure; SameSite=Strict`;
260
+ localStorage.removeItem('basic_auth_state')
249
261
  }
250
262
 
251
263
  const getToken = async (): Promise<string> => {
@@ -308,24 +320,32 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
308
320
  localStorage.setItem('basic_debug', debug ? 'true' : 'false')
309
321
 
310
322
  try {
311
- let cookie_token = getCookie('basic_token')
312
- if (cookie_token !== '') {
313
- setToken(JSON.parse(cookie_token))
314
- }
315
-
316
323
  if (window.location.search.includes('code')) {
317
324
  let code = window.location?.search?.split('code=')[1].split('&')[0]
318
- // log('code found', code)
319
325
 
320
- // todo: check state is valid
321
- setAuthCode(code) // remove this? dont need to store code?
322
- fetchToken(code)
326
+ const state = localStorage.getItem('basic_auth_state')
327
+ if (!state || state !== window.location.search.split('state=')[1].split('&')[0]) {
328
+ log('error: auth state does not match')
329
+ setIsAuthReady(true)
323
330
 
324
- window.history.pushState({}, document.title, "/");
331
+ localStorage.removeItem('basic_auth_state')
332
+ window.history.pushState({}, document.title, "/");
333
+ return
334
+ }
325
335
 
326
- } else {
327
- setIsLoaded(true)
336
+ localStorage.removeItem('basic_auth_state')
337
+
338
+ fetchToken(code)
339
+ } else {
340
+ let cookie_token = getCookie('basic_token')
341
+ if (cookie_token !== '') {
342
+ setToken(JSON.parse(cookie_token))
343
+ } else {
344
+ setIsAuthReady(true)
345
+ }
328
346
  }
347
+
348
+
329
349
  } catch (e) {
330
350
  log('error getting cookie', e)
331
351
  }
@@ -333,6 +353,7 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
333
353
 
334
354
  useEffect(() => {
335
355
  async function fetchUser(acc_token: string) {
356
+ console.info('fetching user')
336
357
  const user = await fetch('https://api.basic.tech/auth/userInfo', {
337
358
  method: 'GET',
338
359
  headers: {
@@ -349,15 +370,23 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
349
370
  } else {
350
371
  // log('user', user)
351
372
  document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;
373
+
374
+ if (window.location.search.includes('code')) {
375
+ window.history.pushState({}, document.title, "/");
376
+ }
377
+
352
378
  setUser(user)
353
379
  setIsSignedIn(true)
354
- setIsLoaded(true)
380
+
381
+ setIsAuthReady(true)
355
382
  }
356
383
  }
357
384
 
358
385
  async function checkToken() {
359
386
  if (!token) {
360
387
  log('error: no user token found')
388
+
389
+ setIsAuthReady(true)
361
390
  return
362
391
  }
363
392
 
@@ -375,8 +404,7 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
375
404
 
376
405
  if (token) {
377
406
  checkToken()
378
- setIsLoaded(true)
379
- }
407
+ }
380
408
  }, [token])
381
409
 
382
410
 
@@ -416,7 +444,7 @@ export function BasicProvider({ children, project_id, schema, debug = false }: {
416
444
  return (
417
445
  <BasicContext.Provider value={{
418
446
  unicorn: "🦄",
419
- isLoaded,
447
+ isAuthReady,
420
448
  isSignedIn,
421
449
  user,
422
450
  signout,
package/src/index.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  import { useBasic, BasicProvider } from "./AuthContext";
2
- import { useLiveQuery as useQuery } from "dexie-react-hooks";
2
+ import { useLiveQuery } from "dexie-react-hooks";
3
+
4
+
5
+ function useQuery(queryable: any) {
6
+ return useLiveQuery(() => {
7
+ if (typeof queryable === 'function') {
8
+ return queryable();
9
+ }
10
+ return queryable;
11
+ }, [queryable], []);
12
+ }
13
+
14
+
3
15
 
4
16
  export {
5
17
  useBasic, BasicProvider, useQuery
6
- }
18
+ }
package/src/sync/index.ts CHANGED
@@ -136,7 +136,6 @@ export class BasicSync extends Dexie {
136
136
  return this.syncable
137
137
  }
138
138
 
139
-
140
139
  collection(name: string) {
141
140
  // TODO: check against schema
142
141
 
@@ -175,12 +174,12 @@ export class BasicSync extends Dexie {
175
174
 
176
175
  // --- READ ---- //
177
176
 
178
- get: (id: string) => {
179
- return this.table(name).get(id)
177
+ get: async (id: string) => {
178
+ return this.table(name).get(id)
180
179
  },
181
180
 
182
- getAll: () => {
183
- return this.table(name).toArray()
181
+ getAll: async () => {
182
+ return this.table(name).toArray();
184
183
  },
185
184
 
186
185
  // --- QUERY ---- //
@@ -193,3 +192,7 @@ export class BasicSync extends Dexie {
193
192
  }
194
193
  }
195
194
  }
195
+
196
+ class QueryMethod {
197
+
198
+ }
@@ -86,6 +86,7 @@ export const syncProtocol = function () {
86
86
 
87
87
  // If socket is closed (network disconnected), inform framework and make it reconnect
88
88
  ws.onclose = function (event) {
89
+ // console.log('🙅 ws.onclose', event)
89
90
  onError("Socket closed: " + event.reason, RECONNECT_DELAY);
90
91
  };
91
92
 
@@ -124,7 +125,6 @@ export const syncProtocol = function () {
124
125
  syncedRevision: syncedRevision,
125
126
  }),
126
127
  );
127
- } else if (requestFromServer.type == "error") {
128
128
  } else if (requestFromServer.type == "changes") {
129
129
  applyRemoteChanges(
130
130
  requestFromServer.changes,