-
Notifications
You must be signed in to change notification settings - Fork 4
Eng 418 create and store roam space password #245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import { type json, getRawBlockProps } from "./getBlockProps"; | ||
| import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; | ||
|
|
||
| export const deNormalizeProps = (props: json): json => | ||
| typeof props === "object" | ||
| ? props === null | ||
| ? null | ||
| : Array.isArray(props) | ||
| ? props.map(deNormalizeProps) | ||
| : Object.fromEntries( | ||
| Object.entries(props).map(([k, v]) => [ | ||
| `:${k}`, | ||
| typeof v === "object" && v !== null && !Array.isArray(v) | ||
| ? deNormalizeProps(v) | ||
| : Array.isArray(v) | ||
| ? v.map(deNormalizeProps) | ||
| : v, | ||
| ]), | ||
| ) | ||
| : props; | ||
|
|
||
| const setBlockProps = ( | ||
| uid: string, | ||
| newProps: Record<string, json>, | ||
| denormalize: boolean = false, | ||
| ) => { | ||
| const baseProps = getRawBlockProps(uid); | ||
| if (typeof baseProps === "object" && !Array.isArray(baseProps)) { | ||
| const props = { | ||
| ...(baseProps || {}), | ||
| ...(denormalize | ||
| ? (deNormalizeProps(newProps) as Record<string, json>) | ||
| : newProps), | ||
| } as Record<string, json>; | ||
| window.roamAlphaAPI.data.block.update({ block: { uid, props } }); | ||
| return props; | ||
| } | ||
| return baseProps; | ||
| }; | ||
|
|
||
| export const testSetBlockProps = ( | ||
| title: string, | ||
| newProps: Record<string, json>, | ||
| ) => { | ||
| const uid = getPageUidByPageTitle(title); | ||
| return uid ? setBlockProps(uid, newProps) : null; | ||
| }; | ||
|
|
||
| export default setBlockProps; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,23 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getNodeEnv } from "roamjs-components/util/env"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getCurrentUserEmail from "roamjs-components/queries/getCurrentUserEmail"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getCurrentUserDisplayName from "roamjs-components/queries/getCurrentUserDisplayName"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getRoamUrl from "roamjs-components/dom/getRoamUrl"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Database } from "@repo/database/types.gen"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { DISCOURSE_CONFIG_PAGE_TITLE } from "~/utils/renderNodeConfigPage"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getBlockProps from "~/utils/getBlockProps"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import setBlockProps from "~/utils/setBlockProps"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| declare const crypto: { randomUUID: () => string }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Platform = Database["public"]["Enums"]["Platform"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export type SupabaseContext = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| platform: Platform; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spaceId: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userId: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spacePassword: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let CONTEXT_CACHE: SupabaseContext | null = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -20,6 +28,22 @@ const base_url = | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? "http://localhost:3000/api/supabase" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : "https://discoursegraphs.com/api/supabase"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const settingsConfigPageUid = getPageUidByPageTitle( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DISCOURSE_CONFIG_PAGE_TITLE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const getOrCreateSpacePassword = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const props = getBlockProps(settingsConfigPageUid); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const existing: string | unknown = props["space-user-password"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (existing && typeof existing === "string") return existing; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // use a uuid as password, at least cryptographically safe | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const password = crypto.randomUUID(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setBlockProps(settingsConfigPageUid, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "space-user-password": password, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return password; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+35
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve type safety and consider error handling. The function has a couple of areas for improvement:
Consider this improvement: const getOrCreateSpacePassword = () => {
const props = getBlockProps(settingsConfigPageUid);
- const existing: string | unknown = props["space-user-password"];
- if (existing && typeof existing === "string") return existing;
+ const existing = props["space-user-password"];
+ if (typeof existing === "string" && existing.length > 0) return existing;
// use a uuid as password, at least cryptographically safe
const password = crypto.randomUUID();
- setBlockProps(settingsConfigPageUid, {
- "space-user-password": password,
- });
+ try {
+ setBlockProps(settingsConfigPageUid, {
+ "space-user-password": password,
+ });
+ } catch (error) {
+ console.error("Failed to store space password:", error);
+ // Consider whether to throw or handle gracefully
+ }
return password;
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Note: Some of this will be more typesafe if rewritten with direct supabase access eventually. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // We're going through nextjs until we have settled security. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -100,12 +124,13 @@ export const getSupabaseContext = async (): Promise<SupabaseContext | null> => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const accountLocalId = window.roamAlphaAPI.user.uid(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const personEmail = getCurrentUserEmail(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const personName = getCurrentUserDisplayName(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const spacePassword = getOrCreateSpacePassword(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const userId = await fetchOrCreatePlatformAccount({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| accountLocalId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| personName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| personEmail, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONTEXT_CACHE = { platform: "Roam", spaceId, userId }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONTEXT_CACHE = { platform: "Roam", spaceId, userId, spacePassword }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error(error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.