Compare commits
5 Commits
jazz-brows
...
jazz-react
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a147c2d28 | ||
|
|
c2b62a0fee | ||
|
|
301458e713 | ||
|
|
1a979b64b3 | ||
|
|
8b7b57fe2c |
5
.changeset/beige-hats-judge.md
Normal file
5
.changeset/beige-hats-judge.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Move session generation to crypto provider
|
||||
@@ -9,6 +9,8 @@
|
||||
"jazz-tools",
|
||||
"jazz-browser",
|
||||
"jazz-browser-media-images",
|
||||
"jazz-browser-auth-clerk",
|
||||
"jazz-react-auth-clerk",
|
||||
"jazz-react",
|
||||
"jazz-nodejs",
|
||||
"jazz-run",
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
{
|
||||
"mode": "pre",
|
||||
"tag": "unique",
|
||||
"tag": "guest-auth",
|
||||
"initialVersions": {
|
||||
"jazz-example-chat": "0.0.82-new-auth.1",
|
||||
"jazz-example-chat-clerk": "0.0.80-new-auth.1",
|
||||
"jazz-inspector": "0.0.59",
|
||||
"jazz-example-pets": "0.0.100-new-auth.1",
|
||||
"jazz-example-todo": "0.0.99-new-auth.1",
|
||||
"cojson": "0.7.34",
|
||||
"cojson-storage-indexeddb": "0.7.34",
|
||||
"cojson-storage-sqlite": "0.7.34",
|
||||
"cojson-transport-ws": "0.7.34",
|
||||
"jazz-example-chat": "0.0.82-unique.2",
|
||||
"jazz-example-chat-clerk": "0.0.80-unique.2",
|
||||
"jazz-inspector": "0.0.60-unique.0",
|
||||
"jazz-example-pets": "0.0.100-unique.2",
|
||||
"jazz-example-todo": "0.0.99-unique.2",
|
||||
"cojson": "0.7.35-unique.2",
|
||||
"cojson-storage-indexeddb": "0.7.35-unique.2",
|
||||
"cojson-storage-sqlite": "0.7.35-unique.2",
|
||||
"cojson-transport-ws": "0.7.35-unique.2",
|
||||
"hash-slash": "0.2.0",
|
||||
"jazz-browser": "0.7.35-new-auth.0",
|
||||
"jazz-browser-auth-clerk": "0.7.33-new-auth.0",
|
||||
"jazz-browser-media-images": "0.7.35-new-auth.0",
|
||||
"jazz-nodejs": "0.7.35-new-auth.0",
|
||||
"jazz-react": "0.7.35-new-auth.1",
|
||||
"jazz-react-auth-clerk": "0.7.33-new-auth.1",
|
||||
"jazz-run": "0.7.35-new-auth.0",
|
||||
"jazz-tools": "0.7.35-new-auth.0"
|
||||
"jazz-browser": "0.7.35-unique.2",
|
||||
"jazz-browser-auth-clerk": "0.7.33-unique.1",
|
||||
"jazz-browser-media-images": "0.7.35-unique.2",
|
||||
"jazz-nodejs": "0.7.35-unique.2",
|
||||
"jazz-react": "0.7.35-unique.2",
|
||||
"jazz-react-auth-clerk": "0.7.33-unique.2",
|
||||
"jazz-run": "0.7.35-unique.2",
|
||||
"jazz-tools": "0.7.35-unique.2"
|
||||
},
|
||||
"changesets": [
|
||||
"beige-hats-judge",
|
||||
"dirty-plants-sniff",
|
||||
"shiny-peaches-grab",
|
||||
"small-students-buy",
|
||||
"small-tables-appear",
|
||||
"smart-mice-camp",
|
||||
"twelve-lobsters-pull"
|
||||
]
|
||||
|
||||
7
.changeset/shiny-peaches-grab.md
Normal file
7
.changeset/shiny-peaches-grab.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"jazz-browser": patch
|
||||
"jazz-react": patch
|
||||
"jazz-tools": patch
|
||||
---
|
||||
|
||||
Make anonymous auth work better
|
||||
7
.changeset/small-tables-appear.md
Normal file
7
.changeset/small-tables-appear.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"jazz-browser": patch
|
||||
"jazz-react": patch
|
||||
"jazz-tools": patch
|
||||
---
|
||||
|
||||
Implement guest auth without account
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.80-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- jazz-react@0.7.35-guest-auth.5
|
||||
- jazz-react-auth-clerk@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.0.80-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
- jazz-react-auth-clerk@0.7.35-guest-auth.4
|
||||
|
||||
## 0.0.80-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
- jazz-react-auth-clerk@0.7.33-guest-auth.3
|
||||
|
||||
## 0.0.80-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat-clerk",
|
||||
"private": true,
|
||||
"version": "0.0.80-unique.2",
|
||||
"version": "0.0.80-guest-auth.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { CoMap, CoList, co, Group, ID } from "jazz-tools";
|
||||
import { createJazzReactApp } from "jazz-react";
|
||||
import { JazzClerkAuth } from "jazz-react-auth-clerk";
|
||||
import { useJazzClerkAuth } from "jazz-react-auth-clerk";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { useIframeHashRouter } from "hash-slash";
|
||||
import { ChatScreen } from "./chatScreen.tsx";
|
||||
import { StrictMode } from "react";
|
||||
|
||||
import { ClerkProvider, SignedIn, useAuth } from "@clerk/clerk-react";
|
||||
import {
|
||||
ClerkProvider,
|
||||
SignInButton,
|
||||
useAuth,
|
||||
useClerk,
|
||||
} from "@clerk/clerk-react";
|
||||
|
||||
export class Message extends CoMap {
|
||||
text = co.string;
|
||||
@@ -17,6 +22,29 @@ export class Chat extends CoList.Of(co.ref(Message)) {}
|
||||
const Jazz = createJazzReactApp();
|
||||
export const { useAccount, useCoState } = Jazz;
|
||||
|
||||
function AuthAndJazz({ children }: { children: React.ReactNode }) {
|
||||
const clerk = useClerk();
|
||||
const [auth, state] = useJazzClerkAuth(clerk);
|
||||
|
||||
return (
|
||||
<>
|
||||
{state.errors.map((error) => (
|
||||
<div key={error}>{error}</div>
|
||||
))}
|
||||
{auth ? (
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://mesh.jazz.tools/?key=chat-example-jazz-clerk@gcmp.io"
|
||||
>
|
||||
{children}
|
||||
</Jazz.Provider>
|
||||
) : (
|
||||
<SignInButton />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
const { signOut } = useAuth();
|
||||
const { me } = useAccount();
|
||||
@@ -49,14 +77,9 @@ createRoot(document.getElementById("root")!).render(
|
||||
publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}
|
||||
afterSignOutUrl="/"
|
||||
>
|
||||
<JazzClerkAuth>
|
||||
<SignedIn>
|
||||
<Jazz.Provider peer="wss://mesh.jazz.tools/?key=chat-example-jazz-clerk@gcmp.io">
|
||||
<App />
|
||||
</Jazz.Provider>
|
||||
</SignedIn>
|
||||
<JazzClerkAuth.BasicUI appName="Chat" />
|
||||
</JazzClerkAuth>
|
||||
<AuthAndJazz>
|
||||
<App />
|
||||
</AuthAndJazz>
|
||||
</ClerkProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.82-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- jazz-react@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.0.82-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.0.82-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.0.82-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.82-unique.2",
|
||||
"version": "0.0.82-guest-auth.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CoMap, CoList, co, Group, ID } from "jazz-tools";
|
||||
import { createJazzReactApp, DemoAuth } from "jazz-react";
|
||||
import { createJazzReactApp, DemoAuthBasicUI, useDemoAuth } from "jazz-react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { useIframeHashRouter } from "hash-slash";
|
||||
import { ChatScreen } from "./chatScreen.tsx";
|
||||
@@ -28,7 +28,8 @@ function App() {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-between w-screen h-screen p-2 dark:bg-black dark:text-white">
|
||||
<div className="rounded mb-5 px-2 py-1 text-sm self-end">
|
||||
{me?.profile?.name} · {/*<button onClick={logOut}>Log Out</button>*/}
|
||||
{me?.profile?.name} ·{" "}
|
||||
{/*<button onClick={logOut}>Log Out</button>*/}
|
||||
</div>
|
||||
{useIframeHashRouter().route({
|
||||
"/": () => createChat() as never,
|
||||
@@ -38,13 +39,27 @@ function App() {
|
||||
);
|
||||
}
|
||||
|
||||
function AuthAndJazz({ children }: { children: React.ReactNode }) {
|
||||
const [auth, state] = useDemoAuth();
|
||||
|
||||
return (
|
||||
<Jazz.Provider
|
||||
auth={auth}
|
||||
peer="wss://mesh.jazz.tools/?key=chat-example-jazz@gcmp.io"
|
||||
>
|
||||
{state.state === "signedIn" ? (
|
||||
children
|
||||
) : (
|
||||
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
|
||||
)}
|
||||
</Jazz.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<DemoAuth>
|
||||
<DemoAuth.BasicUI appName="Jazz Chat" />
|
||||
<Jazz.Provider peer="wss://mesh.jazz.tools/?key=chat-example-jazz@gcmp.io">
|
||||
<App />
|
||||
</Jazz.Provider>
|
||||
</DemoAuth>
|
||||
<AuthAndJazz>
|
||||
<App />
|
||||
</AuthAndJazz>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.60-guest-auth.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- cojson-transport-ws@0.7.35-guest-auth.5
|
||||
|
||||
## 0.0.60-unique.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector",
|
||||
"private": true,
|
||||
"version": "0.0.60-unique.0",
|
||||
"version": "0.0.60-guest-auth.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
RawAccount,
|
||||
AgentSecret,
|
||||
RawAccountID,
|
||||
cojsonInternals,
|
||||
WasmCrypto,
|
||||
} from "cojson";
|
||||
import { createWebSocketPeer } from "cojson-transport-ws";
|
||||
@@ -69,7 +68,7 @@ export default function CoJsonViewerApp() {
|
||||
const node = await LocalNode.withLoadedAccount({
|
||||
accountID: currentAccount.id,
|
||||
accountSecret: currentAccount.secret,
|
||||
sessionID: cojsonInternals.newRandomSessionID(
|
||||
sessionID: crypto.newRandomSessionID(
|
||||
currentAccount.id,
|
||||
),
|
||||
peersToLoadFrom: [wsPeer],
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# jazz-example-pets
|
||||
|
||||
## 0.0.100-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
- jazz-browser-media-images@0.7.35-guest-auth.5
|
||||
|
||||
## 0.0.100-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
- jazz-browser-media-images@0.7.35-guest-auth.4
|
||||
|
||||
## 0.0.100-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
- jazz-browser-media-images@0.7.35-guest-auth.3
|
||||
|
||||
## 0.0.100-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-pets",
|
||||
"private": true,
|
||||
"version": "0.0.100-unique.2",
|
||||
"version": "0.0.100-guest-auth.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -3,20 +3,20 @@ import ReactDOM from "react-dom/client";
|
||||
import { Link, RouterProvider, createHashRouter } from "react-router-dom";
|
||||
import "./index.css";
|
||||
|
||||
import { createJazzReactApp, PasskeyAuth, usePasskeyAuth } from "jazz-react";
|
||||
|
||||
import {
|
||||
Button,
|
||||
ThemeProvider,
|
||||
TitleAndLogo,
|
||||
} from "./basicComponents/index.ts";
|
||||
createJazzReactApp,
|
||||
PasskeyAuthBasicUI,
|
||||
usePasskeyAuth,
|
||||
} from "jazz-react";
|
||||
|
||||
import { ThemeProvider, TitleAndLogo } from "./basicComponents/index.ts";
|
||||
import { NewPetPostForm } from "./3_NewPetPostForm.tsx";
|
||||
import { RatePetPostUI } from "./4_RatePetPostUI.tsx";
|
||||
import { PetAccount, PetPost } from "./1_schema.ts";
|
||||
|
||||
/** Walkthrough: The top-level provider `<WithJazz/>`
|
||||
/** Walkthrough: The top-level provider `<Jazz.Provider/>`
|
||||
*
|
||||
* This shows how to use the top-level provider `<WithJazz/>`,
|
||||
* This shows how to use the top-level provider `<Jazz.Provider/>`,
|
||||
* which provides the rest of the app with a `LocalNode` (used through `useJazz` later),
|
||||
* based on `LocalAuth` that uses PassKeys (aka WebAuthn) to store a user's account secret
|
||||
* - no backend needed. */
|
||||
@@ -27,17 +27,31 @@ const Jazz = createJazzReactApp({ AccountSchema: PetAccount });
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [passkeyAuth, passKeyState] = usePasskeyAuth({ appName });
|
||||
|
||||
return (
|
||||
<Jazz.Provider
|
||||
auth={passkeyAuth}
|
||||
peer="wss://mesh.jazz.tools/?key=pets-example-jazz@gcmp.io"
|
||||
>
|
||||
{passKeyState.state === "signedIn" ? (
|
||||
children
|
||||
) : (
|
||||
<PasskeyAuthBasicUI state={passKeyState} />
|
||||
)}
|
||||
</Jazz.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider>
|
||||
<TitleAndLogo name={appName} />
|
||||
<div className="flex flex-col h-full items-center justify-start gap-10 pt-10 pb-10 px-5">
|
||||
<PasskeyAuth appName={appName}>
|
||||
<Jazz.Provider peer="wss://mesh.jazz.tools/?key=pets-example-jazz@gcmp.io">
|
||||
<App />
|
||||
</Jazz.Provider>
|
||||
<PasskeyAuth.BasicUI />
|
||||
</PasskeyAuth>
|
||||
<JazzAndAuth>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
</React.StrictMode>,
|
||||
@@ -51,8 +65,6 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
*/
|
||||
|
||||
export default function App() {
|
||||
const {state: passKeyState} = usePasskeyAuth();
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
path: "/",
|
||||
@@ -81,7 +93,7 @@ export default function App() {
|
||||
<>
|
||||
<RouterProvider router={router} />
|
||||
|
||||
{passKeyState.state === "signedIn" && (
|
||||
{/* {passKeyState.state === "signedIn" && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
router.navigate("/").then(passKeyState.logOut)
|
||||
@@ -90,7 +102,7 @@ export default function App() {
|
||||
>
|
||||
Log Out
|
||||
</Button>
|
||||
)}
|
||||
)} */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# jazz-example-todo
|
||||
|
||||
## 0.0.99-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.0.99-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.0.99-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.0.99-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-todo",
|
||||
"private": true,
|
||||
"version": "0.0.99-unique.2",
|
||||
"version": "0.0.99-guest-auth.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from "react-router-dom";
|
||||
import "./index.css";
|
||||
|
||||
import { createJazzReactApp, PasskeyAuth, usePasskeyAuth } from "jazz-react";
|
||||
import { createJazzReactApp, PasskeyAuthBasicUI, usePasskeyAuth } from "jazz-react";
|
||||
|
||||
import {
|
||||
Button,
|
||||
@@ -36,17 +36,31 @@ const Jazz = createJazzReactApp<TodoAccount>({
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [passkeyAuth, passKeyState] = usePasskeyAuth({ appName });
|
||||
|
||||
return (
|
||||
<Jazz.Provider
|
||||
auth={passkeyAuth}
|
||||
peer="wss://mesh.jazz.tools/?key=todo-example-jazz@gcmp.io"
|
||||
>
|
||||
{passKeyState.state === "signedIn" ? (
|
||||
children
|
||||
) : (
|
||||
<PasskeyAuthBasicUI state={passKeyState} />
|
||||
)}
|
||||
</Jazz.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
// <React.StrictMode>
|
||||
<ThemeProvider>
|
||||
<TitleAndLogo name={appName} />
|
||||
<div className="flex flex-col h-full items-center justify-start gap-10 pt-10 pb-10 px-5">
|
||||
<PasskeyAuth appName={appName}>
|
||||
<Jazz.Provider peer="wss://mesh.jazz.tools/?key=todo-example-jazz@gcmp.io">
|
||||
<App />
|
||||
</Jazz.Provider>
|
||||
<PasskeyAuth.BasicUI />
|
||||
</PasskeyAuth>
|
||||
<JazzAndAuth>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</div>
|
||||
</ThemeProvider>,
|
||||
// </React.StrictMode>
|
||||
@@ -61,7 +75,6 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
*/
|
||||
export default function App() {
|
||||
// logOut logs out the AuthProvider passed to `<Jazz.Provider/>` above.
|
||||
const { state: passKeyState } = usePasskeyAuth();
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
@@ -90,7 +103,7 @@ export default function App() {
|
||||
<>
|
||||
<RouterProvider router={router} />
|
||||
|
||||
{passKeyState.state === "signedIn" && (
|
||||
{/* {passKeyState.state === "signedIn" && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
router.navigate("/").then(passKeyState.logOut)
|
||||
@@ -99,7 +112,7 @@ export default function App() {
|
||||
>
|
||||
Log Out
|
||||
</Button>
|
||||
)}
|
||||
)} */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-storage-indexeddb
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cojson-storage-indexeddb",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
ControlledAgent,
|
||||
LocalNode,
|
||||
WasmCrypto,
|
||||
cojsonInternals,
|
||||
} from "cojson";
|
||||
import { IDBStorage } from "./index.js";
|
||||
|
||||
@@ -14,7 +13,7 @@ test.skip("Should be able to initialize and load from empty DB", async () => {
|
||||
|
||||
const node = new LocalNode(
|
||||
new ControlledAgent(agentSecret, Crypto),
|
||||
cojsonInternals.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto,
|
||||
);
|
||||
|
||||
@@ -34,7 +33,7 @@ test("Should be able to sync data to database and then load that from a new node
|
||||
|
||||
const node1 = new LocalNode(
|
||||
new ControlledAgent(agentSecret, Crypto),
|
||||
cojsonInternals.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto,
|
||||
);
|
||||
|
||||
@@ -54,7 +53,7 @@ test("Should be able to sync data to database and then load that from a new node
|
||||
|
||||
const node2 = new LocalNode(
|
||||
new ControlledAgent(agentSecret, Crypto),
|
||||
cojsonInternals.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
|
||||
Crypto,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-storage-sqlite
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cojson-storage-sqlite",
|
||||
"type": "module",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# cojson-transport-nodejs-ws
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cojson-transport-ws",
|
||||
"type": "module",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# cojson
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Move session generation to crypto provider
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"types": "src/index.ts",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
SignerID,
|
||||
} from "./crypto/crypto.js";
|
||||
import { JsonObject, JsonValue } from "./jsonValue.js";
|
||||
import { base58 } from "@scure/base";
|
||||
import {
|
||||
PermissionsDef as RulesetDef,
|
||||
determineValidTransactions,
|
||||
@@ -19,7 +18,7 @@ import {
|
||||
import { RawGroup } from "./coValues/group.js";
|
||||
import { LocalNode, ResolveAccountAgentError } from "./localNode.js";
|
||||
import { CoValueKnownState, NewContentMessage } from "./sync.js";
|
||||
import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
|
||||
import { RawCoID, SessionID, TransactionID } from "./ids.js";
|
||||
import { RawAccountID, ControlledAccountOrAgent } from "./coValues/account.js";
|
||||
import { Stringified, parseJSON, stableStringify } from "./jsonStringify.js";
|
||||
import { coreToCoValue } from "./coreToCoValue.js";
|
||||
@@ -53,13 +52,6 @@ export function idforHeader(
|
||||
return `co_z${hash.slice("shortHash_z".length)}`;
|
||||
}
|
||||
|
||||
export function newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
|
||||
return `${accountID}_session_z${base58.encode(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(globalThis as any).crypto.getRandomValues(new Uint8Array(8)),
|
||||
)}`;
|
||||
}
|
||||
|
||||
type SessionLog = {
|
||||
transactions: Transaction[];
|
||||
lastHash?: Hash;
|
||||
|
||||
@@ -133,7 +133,6 @@ export class RawControlledAccount<Meta extends AccountMeta = AccountMeta>
|
||||
}
|
||||
}
|
||||
|
||||
/** @hidden */
|
||||
export class ControlledAgent implements ControlledAccountOrAgent {
|
||||
constructor(
|
||||
public agentSecret: AgentSecret,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { JsonValue } from "../jsonValue.js";
|
||||
import { base58 } from "@scure/base";
|
||||
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
||||
import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
|
||||
import { RawAccountID, SessionID } from "../index.js";
|
||||
|
||||
export type SignerSecret = `signerSecret_z${string}`;
|
||||
export type SignerID = `signer_z${string}`;
|
||||
@@ -290,6 +291,10 @@ export abstract class CryptoProvider<Blake3State = any> {
|
||||
}),
|
||||
)}`;
|
||||
}
|
||||
|
||||
newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
|
||||
return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
|
||||
}
|
||||
}
|
||||
|
||||
export type Hash = `hash_z${string}`;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
CoValueCore,
|
||||
type CoValueUniqueness,
|
||||
newRandomSessionID,
|
||||
MAX_RECOMMENDED_TX_SIZE,
|
||||
idforHeader,
|
||||
} from "./coValueCore.js";
|
||||
@@ -65,7 +64,6 @@ import { FileSystem } from "./storage/FileSystem.js";
|
||||
|
||||
/** @hidden */
|
||||
export const cojsonInternals = {
|
||||
newRandomSessionID,
|
||||
connectedPeers,
|
||||
rawCoIDtoBytes,
|
||||
rawCoIDfromBytes,
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
CoValueCore,
|
||||
CoValueHeader,
|
||||
CoValueUniqueness,
|
||||
newRandomSessionID,
|
||||
} from "./coValueCore.js";
|
||||
import {
|
||||
InviteSecret,
|
||||
@@ -89,7 +88,7 @@ export class LocalNode {
|
||||
const throwawayAgent = crypto.newRandomAgentSecret();
|
||||
const setupNode = new LocalNode(
|
||||
new ControlledAgent(throwawayAgent, crypto),
|
||||
newRandomSessionID(crypto.getAgentID(throwawayAgent)),
|
||||
crypto.newRandomSessionID(crypto.getAgentID(throwawayAgent)),
|
||||
crypto,
|
||||
);
|
||||
|
||||
@@ -97,7 +96,7 @@ export class LocalNode {
|
||||
|
||||
const nodeWithAccount = account.core.node.testWithDifferentAccount(
|
||||
account,
|
||||
newRandomSessionID(account.id),
|
||||
crypto.newRandomSessionID(account.id),
|
||||
);
|
||||
|
||||
const accountOnNodeWithAccount =
|
||||
@@ -183,7 +182,7 @@ export class LocalNode {
|
||||
}): Promise<LocalNode> {
|
||||
const loadingNode = new LocalNode(
|
||||
new ControlledAgent(accountSecret, crypto),
|
||||
newRandomSessionID(accountID),
|
||||
crypto.newRandomSessionID(accountID),
|
||||
crypto,
|
||||
);
|
||||
|
||||
@@ -207,7 +206,7 @@ export class LocalNode {
|
||||
// since this is all synchronous, we can just swap out nodes for the SyncManager
|
||||
const node = loadingNode.testWithDifferentAccount(
|
||||
controlledAccount,
|
||||
sessionID || newRandomSessionID(accountID),
|
||||
sessionID || crypto.newRandomSessionID(accountID),
|
||||
);
|
||||
node.syncManager = loadingNode.syncManager;
|
||||
node.syncManager.local = node;
|
||||
@@ -430,7 +429,7 @@ export class LocalNode {
|
||||
group.core
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteAgentSecret, this.crypto),
|
||||
newRandomSessionID(inviteAgentID),
|
||||
this.crypto.newRandomSessionID(inviteAgentID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -500,7 +499,7 @@ export class LocalNode {
|
||||
)
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(agentSecret, this.crypto),
|
||||
newRandomSessionID(accountAgentID),
|
||||
this.crypto.newRandomSessionID(accountAgentID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { newRandomSessionID } from "../coValueCore.js";
|
||||
import { LocalNode } from "../localNode.js";
|
||||
import { connectedPeers } from "../streamUtils.js";
|
||||
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
||||
@@ -65,7 +64,7 @@ test("Can create account with one node, and then load it on another", async () =
|
||||
const node2 = await LocalNode.withLoadedAccount({
|
||||
accountID,
|
||||
accountSecret,
|
||||
sessionID: newRandomSessionID(accountID),
|
||||
sessionID: Crypto.newRandomSessionID(accountID),
|
||||
peersToLoadFrom: [node1asPeer],
|
||||
crypto: Crypto,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { newRandomSessionID } from "../coValueCore.js";
|
||||
import { expectMap } from "../coValue.js";
|
||||
import {
|
||||
newGroup,
|
||||
@@ -27,7 +26,7 @@ test("Added admin can add a third admin to a group", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
otherAdmin,
|
||||
newRandomSessionID(otherAdmin.id),
|
||||
Crypto.newRandomSessionID(otherAdmin.id),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -47,7 +46,7 @@ test("Added adming can add a third admin to a group (high level)", () => {
|
||||
group.core
|
||||
.testWithDifferentAccount(
|
||||
otherAdmin,
|
||||
newRandomSessionID(otherAdmin.id),
|
||||
Crypto.newRandomSessionID(otherAdmin.id),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -73,7 +72,7 @@ test("Admins can't demote other admins in a group", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
otherAdmin,
|
||||
newRandomSessionID(otherAdmin.id),
|
||||
Crypto.newRandomSessionID(otherAdmin.id),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -89,7 +88,7 @@ test("Admins can't demote other admins in a group (high level)", () => {
|
||||
group.core
|
||||
.testWithDifferentAccount(
|
||||
otherAdmin,
|
||||
newRandomSessionID(otherAdmin.id),
|
||||
Crypto.newRandomSessionID(otherAdmin.id),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -114,7 +113,7 @@ test("Admins an add writers to a group, who can't add admins, writers, or reader
|
||||
|
||||
const groupAsWriter = expectGroup(
|
||||
groupCore
|
||||
.testWithDifferentAccount(writer, newRandomSessionID(writer.id))
|
||||
.testWithDifferentAccount(writer, Crypto.newRandomSessionID(writer.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -142,7 +141,7 @@ test("Admins an add writers to a group, who can't add admins, writers, or reader
|
||||
|
||||
const groupAsWriter = expectGroup(
|
||||
group.core
|
||||
.testWithDifferentAccount(writer, newRandomSessionID(writer.id))
|
||||
.testWithDifferentAccount(writer, Crypto.newRandomSessionID(writer.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -174,7 +173,7 @@ test("Admins can add readers to a group, who can't add admins, writers, or reade
|
||||
|
||||
const groupAsReader = expectGroup(
|
||||
groupCore
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -203,7 +202,7 @@ test("Admins can add readers to a group, who can't add admins, writers, or reade
|
||||
|
||||
const groupAsReader = expectGroup(
|
||||
group.core
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -267,7 +266,7 @@ test("Writers can write to an object that is owned by their group", () => {
|
||||
|
||||
const childObjectAsWriter = childObject.testWithDifferentAccount(
|
||||
writer,
|
||||
newRandomSessionID(writer.id),
|
||||
Crypto.newRandomSessionID(writer.id),
|
||||
);
|
||||
|
||||
const childContentAsWriter = expectMap(
|
||||
@@ -289,7 +288,7 @@ test("Writers can write to an object that is owned by their group (high level)",
|
||||
|
||||
const childObjectAsWriter = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(writer, newRandomSessionID(writer.id))
|
||||
.testWithDifferentAccount(writer, Crypto.newRandomSessionID(writer.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -315,7 +314,7 @@ test("Readers can not write to an object that is owned by their group", () => {
|
||||
|
||||
const childObjectAsReader = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
|
||||
const childContentAsReader = expectMap(
|
||||
@@ -337,7 +336,7 @@ test("Readers can not write to an object that is owned by their group (high leve
|
||||
|
||||
const childObjectAsReader = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -442,7 +441,7 @@ test("Admins can set group read key and then writers can use it to create and re
|
||||
|
||||
const childObjectAsWriter = childObject.testWithDifferentAccount(
|
||||
writer,
|
||||
newRandomSessionID(writer.id),
|
||||
Crypto.newRandomSessionID(writer.id),
|
||||
);
|
||||
|
||||
expect(childObject.getCurrentReadKey().secret).toEqual(readKey);
|
||||
@@ -466,7 +465,7 @@ test("Admins can set group read key and then writers can use it to create and re
|
||||
|
||||
const childObjectAsWriter = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(writer, newRandomSessionID(writer.id))
|
||||
.testWithDifferentAccount(writer, Crypto.newRandomSessionID(writer.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -526,7 +525,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childObjectAsReader = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
|
||||
expect(childObjectAsReader.getCurrentReadKey().secret).toEqual(readKey);
|
||||
@@ -552,7 +551,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childContentAsReader = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -613,7 +612,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childObjectAsReader1 = childObject.testWithDifferentAccount(
|
||||
reader1,
|
||||
newRandomSessionID(reader1.id),
|
||||
Crypto.newRandomSessionID(reader1.id),
|
||||
);
|
||||
|
||||
expect(childObjectAsReader1.getCurrentReadKey().secret).toEqual(readKey);
|
||||
@@ -638,7 +637,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childObjectAsReader2 = childObject.testWithDifferentAccount(
|
||||
reader2,
|
||||
newRandomSessionID(reader2.id),
|
||||
Crypto.newRandomSessionID(reader2.id),
|
||||
);
|
||||
|
||||
expect(childObjectAsReader2.getCurrentReadKey().secret).toEqual(readKey);
|
||||
@@ -666,7 +665,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childContentAsReader1 = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader1, newRandomSessionID(reader1.id))
|
||||
.testWithDifferentAccount(reader1, Crypto.newRandomSessionID(reader1.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -676,7 +675,7 @@ test("Admins can set group read key and then use it to create private transactio
|
||||
|
||||
const childContentAsReader2 = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader2, newRandomSessionID(reader2.id))
|
||||
.testWithDifferentAccount(reader2, Crypto.newRandomSessionID(reader2.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -845,7 +844,7 @@ test("Admins can set group read key, make a private transaction in an owned obje
|
||||
|
||||
const childObjectAsReader = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
|
||||
expect(childObjectAsReader.getCurrentReadKey().secret).toEqual(readKey2);
|
||||
@@ -883,7 +882,7 @@ test("Admins can set group read key, make a private transaction in an owned obje
|
||||
|
||||
const childContentAsReader = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -959,7 +958,7 @@ test("Admins can set group read rey, make a private transaction in an owned obje
|
||||
|
||||
let childObjectAsReader = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -968,7 +967,7 @@ test("Admins can set group read rey, make a private transaction in an owned obje
|
||||
|
||||
let childObjectAsReader2 = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -1024,11 +1023,11 @@ test("Admins can set group read rey, make a private transaction in an owned obje
|
||||
// TODO: make sure these instances of coValues sync between each other so this isn't necessary?
|
||||
childObjectAsReader = childObject.testWithDifferentAccount(
|
||||
reader,
|
||||
newRandomSessionID(reader.id),
|
||||
Crypto.newRandomSessionID(reader.id),
|
||||
);
|
||||
childObjectAsReader2 = childObject.testWithDifferentAccount(
|
||||
reader2,
|
||||
newRandomSessionID(reader2.id),
|
||||
Crypto.newRandomSessionID(reader2.id),
|
||||
);
|
||||
|
||||
expect(
|
||||
@@ -1072,7 +1071,7 @@ test("Admins can set group read rey, make a private transaction in an owned obje
|
||||
|
||||
const childContentAsReader2 = expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader2, newRandomSessionID(reader2.id))
|
||||
.testWithDifferentAccount(reader2, Crypto.newRandomSessionID(reader2.id))
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -1083,7 +1082,7 @@ test("Admins can set group read rey, make a private transaction in an owned obje
|
||||
expect(
|
||||
expectMap(
|
||||
childObject.core
|
||||
.testWithDifferentAccount(reader, newRandomSessionID(reader.id))
|
||||
.testWithDifferentAccount(reader, Crypto.newRandomSessionID(reader.id))
|
||||
.getCurrentContent(),
|
||||
).get("foo3"),
|
||||
).toBeUndefined();
|
||||
@@ -1151,7 +1150,7 @@ test("Admins can create an adminInvite, which can add an admin", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1198,7 +1197,7 @@ test("Admins can create an adminInvite, which can add an admin (high-level)", as
|
||||
|
||||
const nodeAsInvitedAdmin = node.testWithDifferentAccount(
|
||||
new ControlledAgent(invitedAdminSecret, Crypto),
|
||||
newRandomSessionID(invitedAdminID),
|
||||
Crypto.newRandomSessionID(invitedAdminID),
|
||||
);
|
||||
|
||||
await nodeAsInvitedAdmin.acceptInvite(group.id, inviteSecret);
|
||||
@@ -1261,7 +1260,7 @@ test("Admins can create a writerInvite, which can add a writer", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1308,7 +1307,7 @@ test("Admins can create a writerInvite, which can add a writer (high-level)", as
|
||||
|
||||
const nodeAsInvitedWriter = node.testWithDifferentAccount(
|
||||
new ControlledAgent(invitedWriterSecret, Crypto),
|
||||
newRandomSessionID(invitedWriterID),
|
||||
Crypto.newRandomSessionID(invitedWriterID),
|
||||
);
|
||||
|
||||
await nodeAsInvitedWriter.acceptInvite(group.id, inviteSecret);
|
||||
@@ -1364,7 +1363,7 @@ test("Admins can create a readerInvite, which can add a reader", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1401,7 +1400,7 @@ test("Admins can create a readerInvite, which can add a reader (high-level)", as
|
||||
|
||||
const nodeAsInvitedReader = node.testWithDifferentAccount(
|
||||
new ControlledAgent(invitedReaderSecret, Crypto),
|
||||
newRandomSessionID(invitedReaderID),
|
||||
Crypto.newRandomSessionID(invitedReaderID),
|
||||
);
|
||||
|
||||
await nodeAsInvitedReader.acceptInvite(group.id, inviteSecret);
|
||||
@@ -1457,7 +1456,7 @@ test("WriterInvites can not invite admins", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1511,7 +1510,7 @@ test("ReaderInvites can not invite admins", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1565,7 +1564,7 @@ test("ReaderInvites can not invite writers", () => {
|
||||
groupCore
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(inviteSecret, Crypto),
|
||||
newRandomSessionID(inviteID),
|
||||
Crypto.newRandomSessionID(inviteID),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1610,7 +1609,7 @@ test("Can give read permission to 'everyone'", () => {
|
||||
childObject
|
||||
.testWithDifferentAccount(
|
||||
newAccount,
|
||||
newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
Crypto.newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1639,7 +1638,7 @@ test("Can give read permissions to 'everyone' (high-level)", async () => {
|
||||
childObject.core
|
||||
.testWithDifferentAccount(
|
||||
new ControlledAgent(Crypto.newRandomAgentSecret(), Crypto),
|
||||
newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
Crypto.newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1680,7 +1679,7 @@ test("Can give write permission to 'everyone'", async () => {
|
||||
childObject
|
||||
.testWithDifferentAccount(
|
||||
newAccount,
|
||||
newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
Crypto.newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
@@ -1715,7 +1714,7 @@ test("Can give write permissions to 'everyone' (high-level)", async () => {
|
||||
childObject.core
|
||||
.testWithDifferentAccount(
|
||||
newAccount,
|
||||
newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
Crypto.newRandomSessionID(newAccount.currentAgentID()._unsafeUnwrap()),
|
||||
)
|
||||
.getCurrentContent(),
|
||||
);
|
||||
|
||||
@@ -9,7 +9,6 @@ import { RawAccountID } from "../coValues/account.js";
|
||||
import { stableStringify } from "../jsonStringify.js";
|
||||
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
||||
import { expectMap } from "../coValue.js";
|
||||
import { newRandomSessionID } from "../coValueCore.js";
|
||||
|
||||
const Crypto = await WasmCrypto.create();
|
||||
|
||||
@@ -713,7 +712,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
|
||||
crashOnClose: true,
|
||||
});
|
||||
|
||||
const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
||||
const node2 = new LocalNode(admin, Crypto.newRandomSessionID(admin.id), Crypto);
|
||||
|
||||
const [inRx2, inTx2] = newQueuePair();
|
||||
const [outRx2, outTx2] = newQueuePair();
|
||||
@@ -864,7 +863,7 @@ test("Can sync a coValue through a server to another client", async () => {
|
||||
client1.syncManager.addPeer(serverAsPeerForClient1);
|
||||
server.syncManager.addPeer(client1AsPeer);
|
||||
|
||||
const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
||||
const client2 = new LocalNode(admin, Crypto.newRandomSessionID(admin.id), Crypto);
|
||||
|
||||
const [serverAsPeerForClient2, client2AsPeer] = connectedPeers(
|
||||
"serverFor2",
|
||||
@@ -916,7 +915,7 @@ test("Can sync a coValue with private transactions through a server to another c
|
||||
client1.syncManager.addPeer(serverAsPeer);
|
||||
server.syncManager.addPeer(client1AsPeer);
|
||||
|
||||
const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
||||
const client2 = new LocalNode(admin, client1.crypto.newRandomSessionID(admin.id), Crypto);
|
||||
|
||||
const [serverAsOtherPeer, client2AsPeer] = await connectedPeers(
|
||||
"server",
|
||||
@@ -1064,7 +1063,7 @@ test("If we start loading a coValue before connecting to a peer that has it, it
|
||||
const map = group.createMap();
|
||||
map.set("hello", "world", "trusting");
|
||||
|
||||
const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
||||
const node2 = new LocalNode(admin, Crypto.newRandomSessionID(admin.id), Crypto);
|
||||
|
||||
const [node1asPeer, node2asPeer] = await connectedPeers("peer1", "peer2", {
|
||||
peer1role: "server",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { expect } from "vitest";
|
||||
import { newRandomSessionID } from "../coValueCore.js";
|
||||
import { LocalNode } from "../localNode.js";
|
||||
import { expectGroup } from "../typeUtils/expectGroup.js";
|
||||
import { ControlledAgent } from "../coValues/account.js";
|
||||
@@ -14,7 +13,7 @@ export function randomAnonymousAccountAndSessionID(): [
|
||||
] {
|
||||
const agentSecret = Crypto.newRandomAgentSecret();
|
||||
|
||||
const sessionID = newRandomSessionID(Crypto.getAgentID(agentSecret));
|
||||
const sessionID = Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret));
|
||||
|
||||
return [new ControlledAgent(agentSecret, Crypto), sessionID];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- jazz-browser@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.33-guest-auth.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.33-unique.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-browser-auth-clerk",
|
||||
"version": "0.7.33-unique.1",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
@@ -9,8 +9,7 @@
|
||||
"peerDependencies": {
|
||||
"cojson": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-browser": "workspace:*",
|
||||
"@clerk/types": "^3.65.3"
|
||||
"jazz-browser": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext ts,tsx",
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import { Account, AuthMethod, AuthResult, ID } from "jazz-tools";
|
||||
import type { LoadedClerk } from '@clerk/types';
|
||||
import { AgentSecret } from "cojson";
|
||||
|
||||
export type MinimalClerkClient = {
|
||||
user: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
unsafeMetadata: Record<string, any>;
|
||||
fullName: string | null;
|
||||
username: string | null;
|
||||
id: string;
|
||||
update: (args: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
unsafeMetadata: Record<string, any>;
|
||||
}) => Promise<unknown>;
|
||||
} | null | undefined;
|
||||
}
|
||||
|
||||
export class BrowserClerkAuth implements AuthMethod {
|
||||
constructor(
|
||||
public driver: BrowserClerkAuth.Driver,
|
||||
private readonly clerkClient: LoadedClerk,
|
||||
private readonly clerkClient: MinimalClerkClient
|
||||
) {}
|
||||
|
||||
async start(): Promise<AuthResult> {
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-browser-media-images",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# jazz-browser
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- cojson-storage-indexeddb@0.7.35-guest-auth.5
|
||||
- cojson-transport-ws@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make anonymous auth work better
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Implement guest auth without account
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-browser",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -11,14 +11,15 @@ import {
|
||||
CryptoProvider,
|
||||
AuthMethod,
|
||||
createJazzContext,
|
||||
AnonymousJazzAgent,
|
||||
} from "jazz-tools";
|
||||
import { RawAccountID, LSMStorage } from "cojson";
|
||||
import { OPFSFilesystem } from "./OPFSFilesystem.js";
|
||||
import { IDBStorage } from "cojson-storage-indexeddb";
|
||||
import { createWebSocketPeer } from "cojson-transport-ws";
|
||||
export { BrowserDemoAuth } from './auth/DemoAuth.js'
|
||||
export { BrowserPasskeyAuth } from './auth/PasskeyAuth.js'
|
||||
export { BrowserPassphraseAuth } from './auth/PassphraseAuth.js'
|
||||
export { BrowserDemoAuth } from "./auth/DemoAuth.js";
|
||||
export { BrowserPasskeyAuth } from "./auth/PasskeyAuth.js";
|
||||
export { BrowserPassphraseAuth } from "./auth/PassphraseAuth.js";
|
||||
|
||||
/** @category Context Creation */
|
||||
export type BrowserContext<Acc extends Account> = {
|
||||
@@ -27,65 +28,96 @@ export type BrowserContext<Acc extends Account> = {
|
||||
done: () => void;
|
||||
};
|
||||
|
||||
/** @category Context Creation */
|
||||
export async function createJazzBrowserContext<Acc extends Account>({
|
||||
auth,
|
||||
AccountSchema = Account as unknown as CoValueClass<Acc> & {
|
||||
fromNode: (typeof Account)["fromNode"];
|
||||
},
|
||||
peer: peerAddr,
|
||||
reconnectionTimeout: initialReconnectionTimeout = 500,
|
||||
storage = "indexedDB",
|
||||
crypto: customCrypto,
|
||||
}: {
|
||||
export type BrowserGuestContext = {
|
||||
guest: AnonymousJazzAgent;
|
||||
done: () => void;
|
||||
};
|
||||
|
||||
export type BrowserContextOptions<Acc extends Account> = {
|
||||
auth: AuthMethod;
|
||||
AccountSchema: CoValueClass<Acc> & {
|
||||
fromNode: (typeof Account)["fromNode"];
|
||||
};
|
||||
} & BaseBrowserContextOptions;
|
||||
|
||||
export type BaseBrowserContextOptions = {
|
||||
peer: `wss://${string}` | `ws://${string}`;
|
||||
reconnectionTimeout?: number;
|
||||
storage?: "indexedDB" | "singleTabOPFS";
|
||||
crypto?: CryptoProvider;
|
||||
}): Promise<BrowserContext<Acc>> {
|
||||
const crypto = customCrypto || (await WasmCrypto.create());
|
||||
};
|
||||
|
||||
/** @category Context Creation */
|
||||
export async function createJazzBrowserContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc>,
|
||||
): Promise<BrowserContext<Acc>>;
|
||||
export async function createJazzBrowserContext(
|
||||
options: BaseBrowserContextOptions,
|
||||
): Promise<BrowserGuestContext>;
|
||||
export async function createJazzBrowserContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc> | BaseBrowserContextOptions,
|
||||
): Promise<BrowserContext<Acc> | BrowserGuestContext>;
|
||||
export async function createJazzBrowserContext<Acc extends Account>(
|
||||
options: BrowserContextOptions<Acc> | BaseBrowserContextOptions,
|
||||
): Promise<BrowserContext<Acc> | BrowserGuestContext> {
|
||||
const crypto = options.crypto || (await WasmCrypto.create());
|
||||
|
||||
const firstWsPeer = createWebSocketPeer({
|
||||
websocket: new WebSocket(peerAddr),
|
||||
id: peerAddr + "@" + new Date().toISOString(),
|
||||
websocket: new WebSocket(options.peer),
|
||||
id: options.peer + "@" + new Date().toISOString(),
|
||||
role: "server",
|
||||
});
|
||||
let shouldTryToReconnect = true;
|
||||
|
||||
let currentReconnectionTimeout = initialReconnectionTimeout;
|
||||
let currentReconnectionTimeout = options.reconnectionTimeout || 500;
|
||||
|
||||
function onOnline() {
|
||||
console.log("Online, resetting reconnection timeout");
|
||||
currentReconnectionTimeout = initialReconnectionTimeout;
|
||||
currentReconnectionTimeout = options.reconnectionTimeout || 500;
|
||||
}
|
||||
|
||||
window.addEventListener("online", onOnline);
|
||||
|
||||
const { account, done } = await createJazzContext({
|
||||
AccountSchema,
|
||||
auth,
|
||||
crypto: await WasmCrypto.create(),
|
||||
peersToLoadFrom: [
|
||||
storage === "indexedDB"
|
||||
? await IDBStorage.asPeer()
|
||||
: await LSMStorage.asPeer({
|
||||
fs: new OPFSFilesystem(crypto),
|
||||
// trace: true,
|
||||
}),
|
||||
firstWsPeer,
|
||||
],
|
||||
sessionProvider: provideBroswerLockSession,
|
||||
});
|
||||
const context =
|
||||
"auth" in options
|
||||
? await createJazzContext({
|
||||
AccountSchema: options.AccountSchema,
|
||||
auth: options.auth,
|
||||
crypto: await WasmCrypto.create(),
|
||||
peersToLoadFrom: [
|
||||
options.storage === "singleTabOPFS"
|
||||
? await LSMStorage.asPeer({
|
||||
fs: new OPFSFilesystem(crypto),
|
||||
// trace: true,
|
||||
})
|
||||
: await IDBStorage.asPeer(),
|
||||
firstWsPeer,
|
||||
],
|
||||
sessionProvider: provideBroswerLockSession,
|
||||
})
|
||||
: await createJazzContext({
|
||||
crypto: await WasmCrypto.create(),
|
||||
peersToLoadFrom: [
|
||||
options.storage === "singleTabOPFS"
|
||||
? await LSMStorage.asPeer({
|
||||
fs: new OPFSFilesystem(crypto),
|
||||
// trace: true,
|
||||
})
|
||||
: await IDBStorage.asPeer(),
|
||||
firstWsPeer,
|
||||
],
|
||||
});
|
||||
|
||||
const node =
|
||||
"account" in context
|
||||
? context.account._raw.core.node
|
||||
: context.agent.node;
|
||||
|
||||
async function websocketReconnectLoop() {
|
||||
while (shouldTryToReconnect) {
|
||||
if (
|
||||
Object.keys(account._raw.core.node.syncManager.peers).some(
|
||||
(peerId) => peerId.includes(peerAddr),
|
||||
Object.keys(node.syncManager.peers).some((peerId) =>
|
||||
peerId.includes(options.peer),
|
||||
)
|
||||
) {
|
||||
// TODO: this might drain battery, use listeners instead
|
||||
@@ -114,10 +146,10 @@ export async function createJazzBrowserContext<Acc extends Account>({
|
||||
);
|
||||
});
|
||||
|
||||
account._raw.core.node.syncManager.addPeer(
|
||||
node.syncManager.addPeer(
|
||||
createWebSocketPeer({
|
||||
websocket: new WebSocket(peerAddr),
|
||||
id: peerAddr + "@" + new Date().toISOString(),
|
||||
websocket: new WebSocket(options.peer),
|
||||
id: options.peer + "@" + new Date().toISOString(),
|
||||
role: "server",
|
||||
}),
|
||||
);
|
||||
@@ -127,14 +159,23 @@ export async function createJazzBrowserContext<Acc extends Account>({
|
||||
|
||||
void websocketReconnectLoop();
|
||||
|
||||
return {
|
||||
me: account,
|
||||
done: () => {
|
||||
shouldTryToReconnect = false;
|
||||
window.removeEventListener("online", onOnline);
|
||||
done();
|
||||
},
|
||||
};
|
||||
return "account" in context
|
||||
? {
|
||||
me: context.account,
|
||||
done: () => {
|
||||
shouldTryToReconnect = false;
|
||||
window.removeEventListener("online", onOnline);
|
||||
context.done();
|
||||
},
|
||||
}
|
||||
: {
|
||||
guest: context.agent,
|
||||
done: () => {
|
||||
shouldTryToReconnect = false;
|
||||
window.removeEventListener("online", onOnline);
|
||||
context.done();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** @category Auth Providers */
|
||||
@@ -142,7 +183,10 @@ export type SessionProvider = (
|
||||
accountID: ID<Account> | AgentID,
|
||||
) => Promise<SessionID>;
|
||||
|
||||
export function provideBroswerLockSession(accountID: ID<Account> | AgentID) {
|
||||
export function provideBroswerLockSession(
|
||||
accountID: ID<Account> | AgentID,
|
||||
crypto: CryptoProvider,
|
||||
) {
|
||||
let sessionDone!: () => void;
|
||||
const donePromise = new Promise<void>((resolve) => {
|
||||
sessionDone = resolve;
|
||||
@@ -166,7 +210,7 @@ export function provideBroswerLockSession(accountID: ID<Account> | AgentID) {
|
||||
|
||||
const sessionID =
|
||||
localStorage[accountID + "_" + idx] ||
|
||||
cojsonInternals.newRandomSessionID(
|
||||
crypto.newRandomSessionID(
|
||||
accountID as RawAccountID | AgentID,
|
||||
);
|
||||
localStorage[accountID + "_" + idx] = sessionID;
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# jazz-autosub
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- cojson-transport-ws@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"types": "src/index.ts",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:*",
|
||||
"cojson-transport-ws": "workspace:*",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# jazz-browser-media-images
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- jazz-browser-auth-clerk@0.7.35-guest-auth.5
|
||||
- jazz-react@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
- jazz-browser-auth-clerk@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.33-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-react@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
- jazz-browser-auth-clerk@0.7.33-guest-auth.2
|
||||
|
||||
## 0.7.33-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-react-auth-clerk",
|
||||
"version": "0.7.33-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.tsx",
|
||||
@@ -11,7 +11,6 @@
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-browser-auth-clerk": "workspace:*",
|
||||
"@clerk/clerk-react": "^4.0.0",
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,86 +1,29 @@
|
||||
import { SignedOut, SignInButton, useClerk } from "@clerk/clerk-react";
|
||||
import { BrowserClerkAuth } from "jazz-browser-auth-clerk";
|
||||
import { AuthMethodCtx } from "jazz-react";
|
||||
import { useState, useMemo, ReactNode, useContext, createContext } from "react";
|
||||
import { BrowserClerkAuth, MinimalClerkClient } from "jazz-browser-auth-clerk";
|
||||
import { useState, useMemo } from "react";
|
||||
|
||||
export const JazzClerkAuthCtx = createContext<{
|
||||
errors: string[];
|
||||
}>({
|
||||
errors: [],
|
||||
});
|
||||
|
||||
export function JazzClerkAuth({ children }: { children: ReactNode }) {
|
||||
const clerk = useClerk();
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
export function useJazzClerkAuth(clerk: MinimalClerkClient & {
|
||||
signOut: () => Promise<unknown>;
|
||||
}) {
|
||||
const [state, setState] = useState<{ errors: string[] }>({ errors: [] });
|
||||
|
||||
const authMethod = useMemo(() => {
|
||||
return new BrowserClerkAuth(
|
||||
{
|
||||
onError: (error) => {
|
||||
void clerk.signOut();
|
||||
setErrors((errors) => [...errors, error.toString()]);
|
||||
if (clerk.user) {
|
||||
return new BrowserClerkAuth(
|
||||
{
|
||||
onError: (error) => {
|
||||
void clerk.signOut();
|
||||
setState((state) => ({
|
||||
...state,
|
||||
errors: [...state.errors, error.toString()],
|
||||
}));
|
||||
},
|
||||
},
|
||||
},
|
||||
clerk,
|
||||
);
|
||||
}, [clerk]);
|
||||
clerk,
|
||||
);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}, [clerk.user]);
|
||||
|
||||
return (
|
||||
<JazzClerkAuthCtx.Provider value={{ errors }}>
|
||||
<AuthMethodCtx.Provider value={authMethod}>
|
||||
{children}
|
||||
</AuthMethodCtx.Provider>
|
||||
</JazzClerkAuthCtx.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
const JazzClerkBasicUI = ({ appName }: { appName: string }) => {
|
||||
const { errors } = useContext(JazzClerkAuthCtx);
|
||||
const darkMode =
|
||||
typeof window !== "undefined"
|
||||
? window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
: false;
|
||||
return (
|
||||
<SignedOut>
|
||||
<div
|
||||
style={{
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
...(darkMode ? { background: "#000" } : {}),
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "18rem",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2rem",
|
||||
}}
|
||||
>
|
||||
<h1
|
||||
style={{
|
||||
color: darkMode ? "#fff" : "#000",
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
{appName}
|
||||
</h1>
|
||||
<SignInButton />
|
||||
{errors.map((error) => (
|
||||
<div key={error} style={{ color: "red" }}>
|
||||
{error}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</SignedOut>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace JazzClerkAuth {
|
||||
export const BasicUI = JazzClerkBasicUI;
|
||||
return [authMethod, state] as const;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# jazz-react
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- jazz-browser@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make anonymous auth work better
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.4
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Implement guest auth without account
|
||||
- Updated dependencies
|
||||
- jazz-browser@0.7.35-guest-auth.3
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jazz-react",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { createContext, ReactNode, useContext, useMemo, useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { BrowserDemoAuth } from "jazz-browser";
|
||||
import { Account, ID } from "jazz-tools";
|
||||
import { AgentSecret } from "cojson";
|
||||
import { AuthMethodCtx } from "./auth.js";
|
||||
|
||||
type DemoAuthState =
|
||||
type DemoAuthState = (
|
||||
| {
|
||||
state: "uninitialized";
|
||||
}
|
||||
@@ -20,28 +19,23 @@ type DemoAuthState =
|
||||
| {
|
||||
state: "signedIn";
|
||||
logOut: () => void;
|
||||
};
|
||||
|
||||
const DemoAuthStateCtx = createContext<{
|
||||
state: DemoAuthState;
|
||||
}
|
||||
) & {
|
||||
errors: string[];
|
||||
}>({
|
||||
state: { state: "uninitialized" },
|
||||
errors: [],
|
||||
});
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
export function DemoAuth({
|
||||
children,
|
||||
export function useDemoAuth({
|
||||
seedAccounts,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
seedAccounts?: {
|
||||
[name: string]: { accountID: ID<Account>; accountSecret: AgentSecret };
|
||||
};
|
||||
}) {
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
const [state, setState] = useState<DemoAuthState>({ state: "loading" });
|
||||
} = {}) {
|
||||
const [state, setState] = useState<DemoAuthState>({
|
||||
state: "loading",
|
||||
errors: [],
|
||||
});
|
||||
|
||||
const authMethod = useMemo(() => {
|
||||
return new BrowserDemoAuth(
|
||||
@@ -52,30 +46,33 @@ export function DemoAuth({
|
||||
signUp,
|
||||
existingUsers,
|
||||
logInAs,
|
||||
errors: [],
|
||||
});
|
||||
},
|
||||
onSignedIn: ({ logOut }) => {
|
||||
setState({ state: "signedIn", logOut });
|
||||
setState({ state: "signedIn", logOut, errors: [] });
|
||||
},
|
||||
onError: (error) => {
|
||||
setErrors((errors) => [...errors, error.toString()]);
|
||||
setState((current) => ({
|
||||
...current,
|
||||
errors: [...current.errors, error.toString()],
|
||||
}));
|
||||
},
|
||||
},
|
||||
seedAccounts,
|
||||
);
|
||||
}, [seedAccounts]);
|
||||
|
||||
return (
|
||||
<DemoAuthStateCtx.Provider value={{ state, errors }}>
|
||||
<AuthMethodCtx.Provider value={authMethod}>
|
||||
{children}
|
||||
</AuthMethodCtx.Provider>
|
||||
</DemoAuthStateCtx.Provider>
|
||||
);
|
||||
return [authMethod, state] as const;
|
||||
}
|
||||
|
||||
const DemoAuthBasicUI = ({ appName }: { appName: string }) => {
|
||||
const { state, errors } = useContext(DemoAuthStateCtx);
|
||||
export const DemoAuthBasicUI = ({
|
||||
appName,
|
||||
state,
|
||||
}: {
|
||||
appName: string;
|
||||
state: DemoAuthState;
|
||||
}) => {
|
||||
const [username, setUsername] = useState<string>("");
|
||||
const darkMode =
|
||||
typeof window !== "undefined"
|
||||
@@ -112,7 +109,7 @@ const DemoAuthBasicUI = ({ appName }: { appName: string }) => {
|
||||
>
|
||||
{appName}
|
||||
</h1>
|
||||
{errors.map((error) => (
|
||||
{state.errors.map((error) => (
|
||||
<div key={error} style={{ color: "red" }}>
|
||||
{error}
|
||||
</div>
|
||||
@@ -186,9 +183,3 @@ const DemoAuthBasicUI = ({ appName }: { appName: string }) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace DemoAuth {
|
||||
export const BasicUI = DemoAuthBasicUI;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useMemo, useState, ReactNode, createContext, useContext } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { BrowserPasskeyAuth } from "jazz-browser";
|
||||
import { AuthMethodCtx } from "./auth.js";
|
||||
|
||||
export type PasskeyAuthState =
|
||||
export type PasskeyAuthState = (
|
||||
| { state: "uninitialized" }
|
||||
| { state: "loading" }
|
||||
| {
|
||||
@@ -10,29 +9,22 @@ export type PasskeyAuthState =
|
||||
logIn: () => void;
|
||||
signUp: (username: string) => void;
|
||||
}
|
||||
| { state: "signedIn"; logOut: () => void };
|
||||
|
||||
const PasskeyAuthStateCtx = createContext<{
|
||||
state: PasskeyAuthState;
|
||||
| { state: "signedIn"; logOut: () => void }
|
||||
) & {
|
||||
errors: string[];
|
||||
}>({
|
||||
state: { state: "uninitialized" },
|
||||
errors: [],
|
||||
});
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
export function PasskeyAuth({
|
||||
children,
|
||||
export function usePasskeyAuth({
|
||||
appName,
|
||||
appHostname,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
appName: string;
|
||||
appHostname?: string;
|
||||
}) {
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
const [state, setState] = useState<PasskeyAuthState>({
|
||||
state: "loading",
|
||||
errors: [],
|
||||
});
|
||||
|
||||
const authMethod = useMemo(() => {
|
||||
@@ -43,6 +35,7 @@ export function PasskeyAuth({
|
||||
state: "ready",
|
||||
logIn: next.logIn,
|
||||
signUp: next.signUp,
|
||||
errors: [],
|
||||
});
|
||||
},
|
||||
onSignedIn(next) {
|
||||
@@ -50,12 +43,16 @@ export function PasskeyAuth({
|
||||
state: "signedIn",
|
||||
logOut: () => {
|
||||
next.logOut();
|
||||
setState({ state: "loading" });
|
||||
setState({ state: "loading", errors: [] });
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
},
|
||||
onError(error) {
|
||||
setErrors((errors) => [...errors, error.toString()]);
|
||||
setState((state) => ({
|
||||
...state,
|
||||
errors: [...state.errors, error.toString()],
|
||||
}));
|
||||
},
|
||||
},
|
||||
appName,
|
||||
@@ -63,21 +60,10 @@ export function PasskeyAuth({
|
||||
);
|
||||
}, [appName, appHostname]);
|
||||
|
||||
return (
|
||||
<PasskeyAuthStateCtx.Provider value={{ state, errors }}>
|
||||
<AuthMethodCtx.Provider value={authMethod}>
|
||||
{children}
|
||||
</AuthMethodCtx.Provider>
|
||||
</PasskeyAuthStateCtx.Provider>
|
||||
);
|
||||
return [authMethod, state] as const;
|
||||
}
|
||||
|
||||
export const usePasskeyAuth = () => {
|
||||
return useContext(PasskeyAuthStateCtx);
|
||||
};
|
||||
|
||||
const PasskeyAuthBasicUI = () => {
|
||||
const { state, errors } = usePasskeyAuth();
|
||||
export const PasskeyAuthBasicUI = ({ state }: { state: PasskeyAuthState }) => {
|
||||
const [username, setUsername] = useState<string>("");
|
||||
|
||||
if (state.state !== "ready") {
|
||||
@@ -104,9 +90,9 @@ const PasskeyAuthBasicUI = () => {
|
||||
gap: "2rem",
|
||||
}}
|
||||
>
|
||||
{errors.length > 0 && (
|
||||
{state.errors.length > 0 && (
|
||||
<div style={{ color: "red" }}>
|
||||
{errors.map((error, index) => (
|
||||
{state.errors.map((error, index) => (
|
||||
<div key={index}>{error}</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -164,14 +150,3 @@ const PasskeyAuthBasicUI = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace PasskeyAuth {
|
||||
export type Component = (props: {
|
||||
loading: boolean;
|
||||
logIn: () => void;
|
||||
signUp: (username: string) => void;
|
||||
}) => ReactNode;
|
||||
export const BasicUI = PasskeyAuthBasicUI;
|
||||
}
|
||||
|
||||
@@ -1,44 +1,34 @@
|
||||
import { useMemo, useState, ReactNode, createContext, useContext } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { BrowserPassphraseAuth } from "jazz-browser";
|
||||
import { generateMnemonic } from "@scure/bip39";
|
||||
import { cojsonInternals } from "cojson";
|
||||
import { AuthMethodCtx } from "./auth.js";
|
||||
|
||||
export type PassphraseAuthState =
|
||||
| { state: "uninitialized" }
|
||||
(| { state: "uninitialized" }
|
||||
| { state: "loading" }
|
||||
| {
|
||||
state: "ready";
|
||||
logIn: (passphrase: string) => void;
|
||||
signUp: (username: string, passphrase: string) => void;
|
||||
generateRandomPassphrase: () => string;
|
||||
}
|
||||
| { state: "signedIn"; logOut: () => void };
|
||||
|
||||
const PassphraseAuthStateCtx = createContext<{
|
||||
state: PassphraseAuthState;
|
||||
| { state: "signedIn"; logOut: () => void }) & {
|
||||
errors: string[];
|
||||
generateRandomPassphrase: () => string;
|
||||
}>({
|
||||
state: { state: "uninitialized" },
|
||||
errors: [],
|
||||
generateRandomPassphrase: () => "",
|
||||
});
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
export function PassphraseAuth({
|
||||
children,
|
||||
export function usePassphraseAuth({
|
||||
appName,
|
||||
appHostname,
|
||||
wordlist,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
appName: string;
|
||||
appHostname?: string;
|
||||
wordlist: string[];
|
||||
}) {
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
const [state, setState] = useState<PassphraseAuthState>({
|
||||
state: "loading",
|
||||
errors: [],
|
||||
});
|
||||
|
||||
const generateRandomPassphrase = () => {
|
||||
@@ -56,6 +46,8 @@ export function PassphraseAuth({
|
||||
state: "ready",
|
||||
logIn: next.logIn,
|
||||
signUp: next.signUp,
|
||||
generateRandomPassphrase,
|
||||
errors: [],
|
||||
});
|
||||
},
|
||||
onSignedIn(next) {
|
||||
@@ -63,12 +55,13 @@ export function PassphraseAuth({
|
||||
state: "signedIn",
|
||||
logOut: () => {
|
||||
next.logOut();
|
||||
setState({ state: "loading" });
|
||||
setState({ state: "loading", errors: [] });
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
},
|
||||
onError(error) {
|
||||
setErrors((errors) => [...errors, error.toString()]);
|
||||
setState((state) => ({ ...state, errors: [...state.errors, error.toString()] }));
|
||||
},
|
||||
},
|
||||
wordlist,
|
||||
@@ -77,17 +70,10 @@ export function PassphraseAuth({
|
||||
);
|
||||
}, [appName, appHostname, wordlist]);
|
||||
|
||||
return (
|
||||
<PassphraseAuthStateCtx.Provider value={{ state, errors, generateRandomPassphrase }}>
|
||||
<AuthMethodCtx.Provider value={authMethod}>
|
||||
{children}
|
||||
</AuthMethodCtx.Provider>
|
||||
</PassphraseAuthStateCtx.Provider>
|
||||
);
|
||||
return [authMethod, state] as const;
|
||||
}
|
||||
|
||||
const PassphraseAuthBasicUI = () => {
|
||||
const { state, errors, generateRandomPassphrase } = useContext(PassphraseAuthStateCtx);
|
||||
export const PassphraseAuthBasicUI = (state: PassphraseAuthState) => {
|
||||
const [username, setUsername] = useState<string>("");
|
||||
const [passphrase, setPassphrase] = useState<string>("");
|
||||
const [loginPassphrase, setLoginPassphrase] = useState<string>("");
|
||||
@@ -116,9 +102,9 @@ const PassphraseAuthBasicUI = () => {
|
||||
gap: "2rem",
|
||||
}}
|
||||
>
|
||||
{errors.length > 0 && (
|
||||
{state.errors.length > 0 && (
|
||||
<div style={{ color: "red" }}>
|
||||
{errors.map((error, index) => (
|
||||
{state.errors.map((error, index) => (
|
||||
<div key={index}>{error}</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -153,7 +139,7 @@ const PassphraseAuthBasicUI = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
setPassphrase(generateRandomPassphrase());
|
||||
setPassphrase(state.generateRandomPassphrase());
|
||||
e.preventDefault();
|
||||
}}
|
||||
style={{
|
||||
@@ -229,10 +215,4 @@ const PassphraseAuthBasicUI = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/** @category Auth Providers */
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace PassphraseAuth {
|
||||
export const BasicUI = PassphraseAuthBasicUI;
|
||||
}
|
||||
};
|
||||
@@ -1,13 +1,3 @@
|
||||
import React from "react";
|
||||
import { AuthMethod } from "jazz-tools";
|
||||
|
||||
export type AuthState = "loading" | "ready" | "signedIn";
|
||||
|
||||
/** @category Auth Methods */
|
||||
export const AuthMethodCtx = React.createContext<AuthMethod | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
export { DemoAuth } from "./DemoAuth.js";
|
||||
export { PasskeyAuth, usePasskeyAuth } from "./PasskeyAuth.js";
|
||||
export { PassphraseAuth } from "./PassphraseAuth.js";
|
||||
export { useDemoAuth, DemoAuthBasicUI } from "./DemoAuth.js";
|
||||
export { usePasskeyAuth, PasskeyAuthBasicUI } from "./PasskeyAuth.js";
|
||||
export { usePassphraseAuth, PassphraseAuthBasicUI } from "./PassphraseAuth.js";
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
BrowserContext,
|
||||
BrowserGuestContext,
|
||||
consumeInviteLinkFromWindowLocation,
|
||||
createJazzBrowserContext,
|
||||
} from "jazz-browser";
|
||||
@@ -7,6 +9,8 @@ import {
|
||||
import {
|
||||
Account,
|
||||
AccountClass,
|
||||
AnonymousJazzAgent,
|
||||
AuthMethod,
|
||||
CoValue,
|
||||
CoValueClass,
|
||||
DeeplyLoaded,
|
||||
@@ -14,41 +18,48 @@ import {
|
||||
ID,
|
||||
subscribeToCoValue,
|
||||
} from "jazz-tools";
|
||||
import { AuthMethodCtx } from "./auth/auth.js";
|
||||
|
||||
/** @category Context & Hooks */
|
||||
export function createJazzReactApp<Acc extends Account>({
|
||||
AccountSchema = Account as unknown as AccountClass<Acc>,
|
||||
}: {
|
||||
AccountSchema?: AccountClass<Acc>;
|
||||
} = {}): JazzReactContext<Acc> {
|
||||
const JazzContext = React.createContext<Acc | undefined>(undefined);
|
||||
} = {}): JazzReactApp<Acc> {
|
||||
const JazzContext = React.createContext<
|
||||
BrowserContext<Acc> | BrowserGuestContext | undefined
|
||||
>(undefined);
|
||||
|
||||
function Provider({
|
||||
children,
|
||||
auth,
|
||||
peer,
|
||||
storage,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
auth: AuthMethod | "guest";
|
||||
peer: `wss://${string}` | `ws://${string}`;
|
||||
storage?: "indexedDB" | "singleTabOPFS";
|
||||
}) {
|
||||
const [me, setMe] = useState<Acc | undefined>();
|
||||
const auth = useContext(AuthMethodCtx);
|
||||
|
||||
if (!auth) {
|
||||
throw new Error("Jazz.Provider must be used within an Auth Method Provider");
|
||||
}
|
||||
const [ctx, setCtx] = useState<
|
||||
BrowserContext<Acc> | BrowserGuestContext | undefined
|
||||
>();
|
||||
|
||||
useEffect(() => {
|
||||
const promiseWithDoneCallback = createJazzBrowserContext<Acc>({
|
||||
AccountSchema,
|
||||
auth,
|
||||
peer,
|
||||
storage,
|
||||
}).then(({ me, done }) => {
|
||||
setMe(me);
|
||||
return done;
|
||||
const promiseWithDoneCallback = createJazzBrowserContext<Acc>(
|
||||
auth === "guest"
|
||||
? {
|
||||
peer,
|
||||
storage,
|
||||
}
|
||||
: {
|
||||
AccountSchema,
|
||||
auth: auth,
|
||||
peer,
|
||||
storage,
|
||||
},
|
||||
).then((context) => {
|
||||
setCtx(context);
|
||||
return context.done;
|
||||
});
|
||||
|
||||
return () => {
|
||||
@@ -56,10 +67,14 @@ export function createJazzReactApp<Acc extends Account>({
|
||||
};
|
||||
}, [AccountSchema, auth, peer, storage]);
|
||||
|
||||
return <JazzContext.Provider value={me}>{children}</JazzContext.Provider>;
|
||||
return (
|
||||
<JazzContext.Provider value={ctx}>
|
||||
{ctx && children}
|
||||
</JazzContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function useAccount(): { me: Acc | undefined };
|
||||
function useAccount(): { me: Acc };
|
||||
function useAccount<D extends DepthsIn<Acc>>(
|
||||
depth: D,
|
||||
): { me: DeeplyLoaded<Acc, D> | undefined };
|
||||
@@ -68,17 +83,59 @@ export function createJazzReactApp<Acc extends Account>({
|
||||
): { me: Acc | DeeplyLoaded<Acc, D> | undefined } {
|
||||
const context = React.useContext(JazzContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useAccount must be used within a JazzProvider");
|
||||
}
|
||||
|
||||
if (!("me" in context)) {
|
||||
throw new Error(
|
||||
"useAccount can't be used in a JazzProvider with auth === 'guest' - consider using useAccountOrGuest()",
|
||||
);
|
||||
}
|
||||
|
||||
const me = useCoState<Acc, D>(
|
||||
context?.constructor as CoValueClass<Acc>,
|
||||
context?.id,
|
||||
context?.me.constructor as CoValueClass<Acc>,
|
||||
context?.me.id,
|
||||
depth,
|
||||
);
|
||||
|
||||
return {
|
||||
me: depth === undefined ? me || context : me,
|
||||
me: depth === undefined ? me || context.me : me,
|
||||
};
|
||||
}
|
||||
|
||||
function useAccountOrGuest(): { me: Acc | AnonymousJazzAgent };
|
||||
function useAccountOrGuest<D extends DepthsIn<Acc>>(
|
||||
depth: D,
|
||||
): { me: DeeplyLoaded<Acc, D> | undefined | AnonymousJazzAgent };
|
||||
function useAccountOrGuest<D extends DepthsIn<Acc>>(
|
||||
depth?: D,
|
||||
): { me: Acc | DeeplyLoaded<Acc, D> | undefined | AnonymousJazzAgent } {
|
||||
const context = React.useContext(JazzContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useAccountOrGuest must be used within a JazzProvider",
|
||||
);
|
||||
}
|
||||
|
||||
const contextMe = "me" in context ? context.me : undefined;
|
||||
|
||||
const me = useCoState<Acc, D>(
|
||||
contextMe?.constructor as CoValueClass<Acc>,
|
||||
contextMe?.id,
|
||||
depth,
|
||||
);
|
||||
|
||||
if ("me" in context) {
|
||||
return {
|
||||
me: depth === undefined ? me || context.me : me,
|
||||
};
|
||||
} else {
|
||||
return { me: context.guest };
|
||||
}
|
||||
}
|
||||
|
||||
function useCoState<V extends CoValue, D>(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
Schema: CoValueClass<V>,
|
||||
@@ -88,15 +145,25 @@ export function createJazzReactApp<Acc extends Account>({
|
||||
const [state, setState] = useState<{
|
||||
value: DeeplyLoaded<V, D> | undefined;
|
||||
}>({ value: undefined });
|
||||
const me = React.useContext(JazzContext);
|
||||
const context = React.useContext(JazzContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useCoState must be used within a JazzProvider");
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!id || !me) return;
|
||||
if (!id) return;
|
||||
|
||||
return subscribeToCoValue(Schema, id, me, depth, (value) => {
|
||||
setState({ value });
|
||||
});
|
||||
}, [Schema, id, me]);
|
||||
return subscribeToCoValue(
|
||||
Schema,
|
||||
id,
|
||||
"me" in context ? context.me : context.guest,
|
||||
depth,
|
||||
(value) => {
|
||||
setState({ value });
|
||||
},
|
||||
);
|
||||
}, [Schema, id, context]);
|
||||
|
||||
return state.value;
|
||||
}
|
||||
@@ -110,12 +177,25 @@ export function createJazzReactApp<Acc extends Account>({
|
||||
onAccept: (projectID: ID<V>) => void;
|
||||
forValueHint?: string;
|
||||
}): void {
|
||||
const me = React.useContext(JazzContext);
|
||||
const context = React.useContext(JazzContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useAcceptInvite must be used within a JazzProvider",
|
||||
);
|
||||
}
|
||||
|
||||
if (!("me" in context)) {
|
||||
throw new Error(
|
||||
"useAcceptInvite can't be used in a JazzProvider with auth === 'guest'.",
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!me) return;
|
||||
if (!context) return;
|
||||
|
||||
const result = consumeInviteLinkFromWindowLocation({
|
||||
as: me,
|
||||
as: context.me,
|
||||
invitedObjectSchema,
|
||||
forValueHint,
|
||||
});
|
||||
@@ -131,23 +211,25 @@ export function createJazzReactApp<Acc extends Account>({
|
||||
return {
|
||||
Provider,
|
||||
useAccount,
|
||||
useAccountOrGuest,
|
||||
useCoState,
|
||||
useAcceptInvite,
|
||||
};
|
||||
}
|
||||
|
||||
/** @category Context & Hooks */
|
||||
export interface JazzReactContext<Acc extends Account> {
|
||||
export interface JazzReactApp<Acc extends Account> {
|
||||
/** @category Provider Component */
|
||||
Provider: React.FC<{
|
||||
children: React.ReactNode;
|
||||
auth: AuthMethod | "guest";
|
||||
peer: `wss://${string}` | `ws://${string}`;
|
||||
storage?: "indexedDB" | "singleTabOPFS";
|
||||
}>;
|
||||
|
||||
/** @category Hooks */
|
||||
useAccount(): {
|
||||
me: Acc | undefined;
|
||||
me: Acc;
|
||||
};
|
||||
/** @category Hooks */
|
||||
useAccount<D extends DepthsIn<Acc>>(
|
||||
@@ -156,6 +238,15 @@ export interface JazzReactContext<Acc extends Account> {
|
||||
me: DeeplyLoaded<Acc, D> | undefined;
|
||||
};
|
||||
|
||||
/** @category Hooks */
|
||||
useAccountOrGuest(): {
|
||||
me: Acc | AnonymousJazzAgent;
|
||||
};
|
||||
useAccountOrGuest<D extends DepthsIn<Acc>>(
|
||||
depth: D,
|
||||
): {
|
||||
me: DeeplyLoaded<Acc, D> | undefined | AnonymousJazzAgent;
|
||||
};
|
||||
/** @category Hooks */
|
||||
useCoState<V extends CoValue, D>(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# jazz-autosub
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
- cojson-transport-ws@0.7.35-guest-auth.5
|
||||
- jazz-tools@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.4
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- jazz-tools@0.7.35-guest-auth.3
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"bin": "./dist/index.js",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext ts,tsx",
|
||||
"format": "prettier --write './src/**/*.{ts,tsx}'",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# jazz-autosub
|
||||
|
||||
## 0.7.35-guest-auth.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- cojson@0.7.35-guest-auth.5
|
||||
|
||||
## 0.7.35-guest-auth.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Make anonymous auth work better
|
||||
|
||||
## 0.7.35-guest-auth.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Implement guest auth without account
|
||||
|
||||
## 0.7.35-unique.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"types": "./src/index.ts",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "0.7.35-unique.2",
|
||||
"version": "0.7.35-guest-auth.5",
|
||||
"dependencies": {
|
||||
"cojson": "workspace:*",
|
||||
"fast-check": "^3.17.2"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LocalNode, cojsonInternals } from "cojson";
|
||||
import type {
|
||||
import {
|
||||
AgentSecret,
|
||||
CoID,
|
||||
CryptoProvider,
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
RefIfCoValue,
|
||||
DeeplyLoaded,
|
||||
DepthsIn,
|
||||
AnonymousJazzAgent,
|
||||
} from "../internal.js";
|
||||
import {
|
||||
Group,
|
||||
@@ -67,8 +68,13 @@ export class Account extends CoValueBase implements CoValue {
|
||||
get _owner(): Account {
|
||||
return this as Account;
|
||||
}
|
||||
get _loadedAs(): Account {
|
||||
return this.isMe ? this : Account.fromNode(this._raw.core.node);
|
||||
get _loadedAs(): Account | AnonymousJazzAgent {
|
||||
if (this.isMe) return this;
|
||||
|
||||
if (this._raw.core.node.account instanceof RawAccount) {
|
||||
return Account.fromRaw(this._raw.core.node.account);
|
||||
}
|
||||
return new AnonymousJazzAgent(this._raw.core.node);
|
||||
}
|
||||
|
||||
declare profile: Profile | null;
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
} from "../internal.js";
|
||||
import {
|
||||
Account,
|
||||
AnonymousJazzAgent,
|
||||
Group,
|
||||
ItemsSym,
|
||||
Ref,
|
||||
@@ -163,7 +164,10 @@ export class CoList<Item = any> extends Array<Item> implements CoValue {
|
||||
}
|
||||
|
||||
get _loadedAs() {
|
||||
return Account.fromNode(this._raw.core.node);
|
||||
if (this._raw.core.node.account instanceof RawAccount) {
|
||||
return Account.fromRaw(this._raw.core.node.account);
|
||||
}
|
||||
return new AnonymousJazzAgent(this._raw.core.node);
|
||||
}
|
||||
|
||||
static get [Symbol.species]() {
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
DepthsIn,
|
||||
DeeplyLoaded,
|
||||
CoValueClass,
|
||||
AnonymousJazzAgent,
|
||||
} from "../internal.js";
|
||||
import {
|
||||
Account,
|
||||
@@ -194,11 +195,6 @@ export class CoMap extends CoValueBase implements CoValue {
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
get _loadedAs() {
|
||||
return Account.fromNode(this._raw.core.node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
constructor(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -445,9 +441,9 @@ export class CoMap extends CoValueBase implements CoValue {
|
||||
|
||||
static findUnique<M extends CoMap>(
|
||||
this: CoValueClass<M>,
|
||||
unique: CoValueUniqueness['uniqueness'],
|
||||
unique: CoValueUniqueness["uniqueness"],
|
||||
ownerID: ID<Account> | ID<Group>,
|
||||
as: Account | Group,
|
||||
as: Account | Group | AnonymousJazzAgent,
|
||||
) {
|
||||
const header = {
|
||||
type: "comap" as const,
|
||||
@@ -458,10 +454,9 @@ export class CoMap extends CoValueBase implements CoValue {
|
||||
meta: null,
|
||||
uniqueness: unique,
|
||||
};
|
||||
return cojsonInternals.idforHeader(
|
||||
header,
|
||||
as._raw.core.crypto,
|
||||
) as ID<M>;
|
||||
const crypto =
|
||||
as._type === "Anonymous" ? as.node.crypto : as._raw.core.crypto;
|
||||
return cojsonInternals.idforHeader(header, crypto) as ID<M>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import type {
|
||||
CoValueClass,
|
||||
DeeplyLoaded,
|
||||
DepthsIn,
|
||||
AnonymousJazzAgent,
|
||||
} from "../internal.js";
|
||||
import {
|
||||
ItemsSym,
|
||||
@@ -77,13 +78,21 @@ export class CoStream<Item = any> extends CoValueBase implements CoValue {
|
||||
[key: ID<Account>]: CoStreamEntry<Item>;
|
||||
|
||||
get byMe(): CoStreamEntry<Item> | undefined {
|
||||
return this[this._loadedAs.id];
|
||||
if (this._loadedAs._type === "Account") {
|
||||
return this[this._loadedAs.id];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
perSession!: {
|
||||
[key: SessionID]: CoStreamEntry<Item>;
|
||||
};
|
||||
get inCurrentSession(): CoStreamEntry<Item> | undefined {
|
||||
return this.perSession[this._loadedAs.sessionID!];
|
||||
if (this._loadedAs._type === "Account") {
|
||||
return this.perSession[this._loadedAs.sessionID!];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
@@ -233,7 +242,7 @@ function entryFromRawEntry<Item>(
|
||||
at: Date;
|
||||
value: JsonValue;
|
||||
},
|
||||
loadedAs: Account,
|
||||
loadedAs: Account | AnonymousJazzAgent,
|
||||
accountID: ID<Account> | undefined,
|
||||
itemField: Schema,
|
||||
): Omit<CoStreamEntry<Item>, "all"> {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Ref,
|
||||
inspect,
|
||||
subscriptionsScopes,
|
||||
AnonymousJazzAgent,
|
||||
} from "../internal.js";
|
||||
import { fulfillsDepth } from "./deepLoading.js";
|
||||
|
||||
@@ -35,7 +36,7 @@ export interface CoValue {
|
||||
/** @category Internals */
|
||||
_raw: RawCoValue;
|
||||
/** @internal */
|
||||
readonly _loadedAs: Account;
|
||||
readonly _loadedAs: Account | AnonymousJazzAgent;
|
||||
/** @category Stringifying & Inspection */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
toJSON(key?: string, seenAbove?: ID<CoValue>[]): any[] | object | string;
|
||||
@@ -86,7 +87,10 @@ export class CoValueBase implements CoValue {
|
||||
|
||||
/** @private */
|
||||
get _loadedAs() {
|
||||
return Account.fromNode(this._raw.core.node);
|
||||
if (this._raw.core.node.account instanceof RawAccount) {
|
||||
return Account.fromRaw(this._raw.core.node.account);
|
||||
}
|
||||
return new AnonymousJazzAgent(this._raw.core.node);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -134,7 +138,7 @@ export class CoValueBase implements CoValue {
|
||||
export function loadCoValue<V extends CoValue, Depth>(
|
||||
cls: CoValueClass<V>,
|
||||
id: ID<V>,
|
||||
as: Account,
|
||||
as: Account | AnonymousJazzAgent,
|
||||
depth: Depth & DepthsIn<V>,
|
||||
): Promise<DeeplyLoaded<V, Depth> | undefined> {
|
||||
return new Promise((resolve) => {
|
||||
@@ -170,7 +174,7 @@ export function ensureCoValueLoaded<V extends CoValue, Depth>(
|
||||
export function subscribeToCoValue<V extends CoValue, Depth>(
|
||||
cls: CoValueClass<V>,
|
||||
id: ID<V>,
|
||||
as: Account,
|
||||
as: Account | AnonymousJazzAgent,
|
||||
depth: Depth & DepthsIn<V>,
|
||||
listener: (value: DeeplyLoaded<V, Depth>) => void,
|
||||
onUnavailable?: () => void,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
AgentSecret,
|
||||
CoID,
|
||||
cojsonInternals,
|
||||
ControlledAgent,
|
||||
CryptoProvider,
|
||||
LocalNode,
|
||||
Peer,
|
||||
@@ -48,38 +48,75 @@ export const fixedCredentialsAuth = (credentials: {
|
||||
};
|
||||
};
|
||||
|
||||
export async function randomSessionProvider(accountID: ID<Account>) {
|
||||
export async function randomSessionProvider(
|
||||
accountID: ID<Account>,
|
||||
crypto: CryptoProvider,
|
||||
) {
|
||||
return {
|
||||
sessionID: cojsonInternals.newRandomSessionID(
|
||||
sessionID: crypto.newRandomSessionID(
|
||||
accountID as unknown as RawAccountID,
|
||||
),
|
||||
sessionDone: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
export async function createJazzContext<Acc extends Account>({
|
||||
AccountSchema = Account as unknown as AccountClass<Acc>,
|
||||
auth,
|
||||
sessionProvider,
|
||||
peersToLoadFrom,
|
||||
crypto,
|
||||
}: {
|
||||
type ContextParamsWithAuth<Acc extends Account> = {
|
||||
AccountSchema?: AccountClass<Acc>;
|
||||
auth: AuthMethod;
|
||||
sessionProvider: (
|
||||
accountID: ID<Account>,
|
||||
crypto: CryptoProvider,
|
||||
) => Promise<{ sessionID: SessionID; sessionDone: () => void }>;
|
||||
} & BaseContextParams;
|
||||
|
||||
type BaseContextParams = {
|
||||
peersToLoadFrom: Peer[];
|
||||
crypto: CryptoProvider;
|
||||
}): Promise<{ account: Acc; done: () => void }> {
|
||||
};
|
||||
|
||||
export async function createJazzContext<Acc extends Account>({
|
||||
AccountSchema,
|
||||
auth,
|
||||
sessionProvider,
|
||||
peersToLoadFrom,
|
||||
crypto,
|
||||
}: ContextParamsWithAuth<Acc>): Promise<{ account: Acc; done: () => void }>;
|
||||
export async function createJazzContext({
|
||||
peersToLoadFrom,
|
||||
crypto,
|
||||
}: BaseContextParams): Promise<{ agent: AnonymousJazzAgent; done: () => void }>;
|
||||
export async function createJazzContext<Acc extends Account>(
|
||||
options: ContextParamsWithAuth<Acc> | BaseContextParams,
|
||||
): Promise<
|
||||
| { account: Acc; done: () => void }
|
||||
| { agent: AnonymousJazzAgent; done: () => void }
|
||||
>
|
||||
export async function createJazzContext<Acc extends Account>(
|
||||
options: ContextParamsWithAuth<Acc> | BaseContextParams,
|
||||
): Promise<
|
||||
| { account: Acc; done: () => void }
|
||||
| { agent: AnonymousJazzAgent; done: () => void }
|
||||
> {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
if (!("auth" in options)) {
|
||||
return createAnonymousJazzContext({
|
||||
peersToLoadFrom: options.peersToLoadFrom,
|
||||
crypto: options.crypto,
|
||||
});
|
||||
}
|
||||
|
||||
const { auth, sessionProvider, peersToLoadFrom, crypto } = options;
|
||||
const AccountSchema =
|
||||
options.AccountSchema ?? (Account as unknown as AccountClass<Acc>);
|
||||
|
||||
const authResult = await auth.start(crypto);
|
||||
|
||||
if (authResult.type === "existing") {
|
||||
try {
|
||||
const { sessionID, sessionDone } = await sessionProvider(
|
||||
authResult.credentials.accountID,
|
||||
crypto,
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -160,3 +197,34 @@ export async function createJazzContext<Acc extends Account>({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class AnonymousJazzAgent {
|
||||
_type = "Anonymous" as const;
|
||||
constructor(public node: LocalNode) {}
|
||||
}
|
||||
|
||||
export async function createAnonymousJazzContext({
|
||||
peersToLoadFrom,
|
||||
crypto,
|
||||
}: {
|
||||
peersToLoadFrom: Peer[];
|
||||
crypto: CryptoProvider;
|
||||
}): Promise<{ agent: AnonymousJazzAgent; done: () => void }> {
|
||||
const agentSecret = crypto.newRandomAgentSecret();
|
||||
const rawAgent = new ControlledAgent(agentSecret, crypto);
|
||||
|
||||
const node = new LocalNode(
|
||||
rawAgent,
|
||||
crypto.newRandomSessionID(rawAgent.id),
|
||||
crypto,
|
||||
);
|
||||
|
||||
for (const peer of peersToLoadFrom) {
|
||||
node.syncManager.addPeer(peer);
|
||||
}
|
||||
|
||||
return {
|
||||
agent: new AnonymousJazzAgent(node),
|
||||
done: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { CoID, RawCoValue } from "cojson";
|
||||
import type {
|
||||
Account,
|
||||
AnonymousJazzAgent,
|
||||
CoValue,
|
||||
ID,
|
||||
RefEncoded,
|
||||
@@ -19,7 +20,7 @@ const TRACE_ACCESSES = false;
|
||||
export class Ref<out V extends CoValue> {
|
||||
constructor(
|
||||
readonly id: ID<V>,
|
||||
readonly controlledAccount: Account,
|
||||
readonly controlledAccount: Account | AnonymousJazzAgent,
|
||||
readonly schema: RefEncoded<V>,
|
||||
) {
|
||||
if (!isRefEncoded(schema)) {
|
||||
@@ -28,9 +29,11 @@ export class Ref<out V extends CoValue> {
|
||||
}
|
||||
|
||||
get value() {
|
||||
const raw = this.controlledAccount._raw.core.node.getLoaded(
|
||||
this.id as unknown as CoID<RawCoValue>,
|
||||
);
|
||||
const node =
|
||||
"node" in this.controlledAccount
|
||||
? this.controlledAccount.node
|
||||
: this.controlledAccount._raw.core.node;
|
||||
const raw = node.getLoaded(this.id as unknown as CoID<RawCoValue>);
|
||||
if (raw) {
|
||||
let value = refCache.get(raw);
|
||||
if (value) {
|
||||
@@ -48,7 +51,11 @@ export class Ref<out V extends CoValue> {
|
||||
private async loadHelper(options?: {
|
||||
onProgress: (p: number) => void;
|
||||
}): Promise<V | "unavailable"> {
|
||||
const raw = await this.controlledAccount._raw.core.node.load(
|
||||
const node =
|
||||
"node" in this.controlledAccount
|
||||
? this.controlledAccount.node
|
||||
: this.controlledAccount._raw.core.node;
|
||||
const raw = await node.load(
|
||||
this.id as unknown as CoID<RawCoValue>,
|
||||
options?.onProgress,
|
||||
);
|
||||
@@ -117,7 +124,7 @@ export class Ref<out V extends CoValue> {
|
||||
export function makeRefs<Keys extends string | number>(
|
||||
getIdForKey: (key: Keys) => ID<CoValue> | undefined,
|
||||
getKeysWithIds: () => Keys[],
|
||||
controlledAccount: Account,
|
||||
controlledAccount: Account | AnonymousJazzAgent,
|
||||
refSchemaForKey: (key: Keys) => RefEncoded<CoValue>,
|
||||
): { [K in Keys]: Ref<CoValue> } & {
|
||||
[Symbol.iterator]: () => IterableIterator<Ref<CoValue>>;
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
ID,
|
||||
CoValueClass,
|
||||
CoValueFromRaw,
|
||||
AnonymousJazzAgent,
|
||||
} from "../internal.js";
|
||||
|
||||
export const subscriptionsScopes = new WeakMap<
|
||||
@@ -17,7 +18,7 @@ const TRACE_INVALIDATIONS = false;
|
||||
|
||||
export class SubscriptionScope<Root extends CoValue> {
|
||||
scopeID: string = `scope-${Math.random().toString(36).slice(2)}`;
|
||||
subscriber: Account;
|
||||
subscriber: Account | AnonymousJazzAgent;
|
||||
entries = new Map<
|
||||
ID<CoValue>,
|
||||
| { state: "loading"; immediatelyUnsub?: boolean }
|
||||
@@ -89,32 +90,34 @@ export class SubscriptionScope<Root extends CoValue> {
|
||||
immediatelyUnsub: false,
|
||||
} as const;
|
||||
this.entries.set(accessedOrSetId, loadingEntry);
|
||||
void this.subscriber._raw.core.node
|
||||
.loadCoValueCore(accessedOrSetId)
|
||||
.then((core) => {
|
||||
if (
|
||||
loadingEntry.state === "loading" &&
|
||||
loadingEntry.immediatelyUnsub
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (core !== "unavailable") {
|
||||
const entry = {
|
||||
state: "loaded" as const,
|
||||
rawUnsub: () => {}, // placeholder
|
||||
};
|
||||
this.entries.set(accessedOrSetId, entry);
|
||||
const node =
|
||||
this.subscriber._type === "Account"
|
||||
? this.subscriber._raw.core.node
|
||||
: this.subscriber.node;
|
||||
void node.loadCoValueCore(accessedOrSetId).then((core) => {
|
||||
if (
|
||||
loadingEntry.state === "loading" &&
|
||||
loadingEntry.immediatelyUnsub
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (core !== "unavailable") {
|
||||
const entry = {
|
||||
state: "loaded" as const,
|
||||
rawUnsub: () => {}, // placeholder
|
||||
};
|
||||
this.entries.set(accessedOrSetId, entry);
|
||||
|
||||
const rawUnsub = core.subscribe((rawUpdate) => {
|
||||
// console.log("ref update", this.scopeID, accessedOrSetId, JSON.stringify(rawUpdate))
|
||||
if (!rawUpdate) return;
|
||||
this.invalidate(accessedOrSetId);
|
||||
this.scheduleUpdate();
|
||||
});
|
||||
const rawUnsub = core.subscribe((rawUpdate) => {
|
||||
// console.log("ref update", this.scopeID, accessedOrSetId, JSON.stringify(rawUpdate))
|
||||
if (!rawUpdate) return;
|
||||
this.invalidate(accessedOrSetId);
|
||||
this.scheduleUpdate();
|
||||
});
|
||||
|
||||
entry.rawUnsub = rawUnsub;
|
||||
}
|
||||
});
|
||||
entry.rawUnsub = rawUnsub;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,4 +34,6 @@ export {
|
||||
type AuthResult,
|
||||
createJazzContext,
|
||||
fixedCredentialsAuth,
|
||||
AnonymousJazzAgent,
|
||||
createAnonymousJazzContext,
|
||||
} from "./internal.js";
|
||||
|
||||
49
pnpm-lock.yaml
generated
49
pnpm-lock.yaml
generated
@@ -671,9 +671,6 @@ importers:
|
||||
|
||||
packages/jazz-browser-auth-clerk:
|
||||
dependencies:
|
||||
'@clerk/types':
|
||||
specifier: ^3.65.3
|
||||
version: 3.65.3
|
||||
cojson:
|
||||
specifier: workspace:*
|
||||
version: link:../cojson
|
||||
@@ -765,9 +762,6 @@ importers:
|
||||
|
||||
packages/jazz-react-auth-clerk:
|
||||
dependencies:
|
||||
'@clerk/clerk-react':
|
||||
specifier: ^4.0.0
|
||||
version: 4.32.3(react@18.2.0)
|
||||
cojson:
|
||||
specifier: workspace:*
|
||||
version: link:../cojson
|
||||
@@ -928,12 +922,6 @@ packages:
|
||||
'@changesets/write@0.3.1':
|
||||
resolution: {integrity: sha512-SyGtMXzH3qFqlHKcvFY2eX+6b0NGiFcNav8AFsYwy5l8hejOeoeTDemu5Yjmke2V5jpzY+pBvM0vCCQ3gdZpfw==}
|
||||
|
||||
'@clerk/clerk-react@4.32.3':
|
||||
resolution: {integrity: sha512-qLKazE3ERUcQwzIaRzLH7BszConlTRsDZuW5hDrFA4T3KNv5ReaFP7W2nW+dvfCz1UC6RC3E4622k1fmfXC6+A==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
react: '>=16'
|
||||
|
||||
'@clerk/clerk-react@5.4.1':
|
||||
resolution: {integrity: sha512-r0P5kEFWh3Cyl+PrNWM7oW/+0aPaB0Zp80MzQLTvpSSGgemYoDHgybmc2Twc4rS0GOJ455y5uSB1smTh0G+ztw==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
@@ -941,14 +929,6 @@ packages:
|
||||
react: '>=18 || >=19.0.0-beta'
|
||||
react-dom: '>=18 || >=19.0.0-beta'
|
||||
|
||||
'@clerk/shared@1.4.1':
|
||||
resolution: {integrity: sha512-3rlZy0Hadnb1dw6x+4MGEC7dpZLlIVY3mZTwWRRS4CILWowVAccwfW84paN2XNlM12lJgMc+w66WNdw19XFtpg==}
|
||||
peerDependencies:
|
||||
react: '>=16'
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
|
||||
'@clerk/shared@2.5.1':
|
||||
resolution: {integrity: sha512-RslzZvjolG8ToZlegV8XPEkINQ4XM23lO2xS6ZtJEeGzRzchkpEBUOYywjG6aGtJDByWBY2OxyrPaa5rwx1XEg==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
@@ -961,10 +941,6 @@ packages:
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
'@clerk/types@3.65.3':
|
||||
resolution: {integrity: sha512-q2BvCBK3H9SxLyoSsybAFTcbW6s50JPY8JACFqzenBbByOyolgIXPJNE0MStUUnNc7lRrPDkoLuZZf71X7JqIw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@clerk/types@4.13.1':
|
||||
resolution: {integrity: sha512-AfFTA1Du0pog62CSl23Y8NNDN+iHwXdUQAp/sQ/LbE+/wYBOMSaV5d+cS5F4HX+/uzXgKsc3BpCNI/Th3CLNHg==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
@@ -3324,10 +3300,6 @@ packages:
|
||||
js-cookie@2.2.1:
|
||||
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
|
||||
|
||||
js-cookie@3.0.1:
|
||||
resolution: {integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
js-cookie@3.0.5:
|
||||
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -5171,13 +5143,6 @@ snapshots:
|
||||
human-id: 1.0.2
|
||||
prettier: 2.8.8
|
||||
|
||||
'@clerk/clerk-react@4.32.3(react@18.2.0)':
|
||||
dependencies:
|
||||
'@clerk/shared': 1.4.1(react@18.2.0)
|
||||
'@clerk/types': 3.65.3
|
||||
react: 18.2.0
|
||||
tslib: 2.4.1
|
||||
|
||||
'@clerk/clerk-react@5.4.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
'@clerk/shared': 2.5.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
@@ -5186,14 +5151,6 @@ snapshots:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
tslib: 2.4.1
|
||||
|
||||
'@clerk/shared@1.4.1(react@18.2.0)':
|
||||
dependencies:
|
||||
glob-to-regexp: 0.4.1
|
||||
js-cookie: 3.0.1
|
||||
swr: 2.2.0(react@18.2.0)
|
||||
optionalDependencies:
|
||||
react: 18.2.0
|
||||
|
||||
'@clerk/shared@2.5.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
'@clerk/types': 4.13.1
|
||||
@@ -5205,10 +5162,6 @@ snapshots:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
'@clerk/types@3.65.3':
|
||||
dependencies:
|
||||
csstype: 3.1.1
|
||||
|
||||
'@clerk/types@4.13.1':
|
||||
dependencies:
|
||||
csstype: 3.1.1
|
||||
@@ -7727,8 +7680,6 @@ snapshots:
|
||||
|
||||
js-cookie@2.2.1: {}
|
||||
|
||||
js-cookie@3.0.1: {}
|
||||
|
||||
js-cookie@3.0.5: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
Reference in New Issue
Block a user