@dbx-tools/ui-email 0.6.72 → 0.6.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -24,11 +24,11 @@
24
24
  "typescript": "^5.9.3"
25
25
  },
26
26
  "dependencies": {
27
- "@dbx-tools/shared-core": "0.6.72",
28
- "@dbx-tools/shared-email": "0.6.72",
29
- "@dbx-tools/shared-email-template": "0.6.72",
30
- "@dbx-tools/ui-appkit": "0.6.72",
31
- "@dbx-tools/ui-branding": "0.6.72",
27
+ "@dbx-tools/shared-core": "0.6.73",
28
+ "@dbx-tools/shared-email": "0.6.73",
29
+ "@dbx-tools/shared-email-template": "0.6.73",
30
+ "@dbx-tools/ui-appkit": "0.6.73",
31
+ "@dbx-tools/ui-branding": "0.6.73",
32
32
  "lucide-react": "^0.554.0",
33
33
  "react": "^19.2.4",
34
34
  "react-dom": "^19.2.4"
@@ -37,7 +37,7 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "version": "0.6.72",
40
+ "version": "0.6.73",
41
41
  "type": "module",
42
42
  "exports": {
43
43
  "./react": "./src/react/index.ts",
@@ -5,8 +5,8 @@ import { BrandIcon, useBrand } from "@dbx-tools/ui-branding/react";
5
5
  import { type FormEvent, type ReactNode, useCallback, useEffect, useState } from "react";
6
6
 
7
7
  /**
8
- * Email one-time-code sign-in gate for an app fronted by the `@dbx-tools/email`
9
- * auth plugin - an app reachable on the public internet, where the hosting
8
+ * Email one-time-code sign-in gate for an app fronted by the
9
+ * `@dbx-tools/tunnel` `authGate` plugin - an app reachable on the public internet, where the hosting
10
10
  * platform's own identity-aware proxy is not in the request path.
11
11
  *
12
12
  * Wrap the app in `<AuthGate>...</AuthGate>`. It calls the plugin's
@@ -38,6 +38,7 @@ async function postJson<T>(path: string, body: unknown): Promise<T> {
38
38
  body: JSON.stringify(body),
39
39
  credentials: "same-origin",
40
40
  });
41
+ if (!res.ok) throw new Error(`Authentication request failed (${res.status})`);
41
42
  return (await res.json()) as T;
42
43
  }
43
44
 
@@ -68,7 +69,10 @@ export function AuthGate({ children, title, description }: AuthGateProps): React
68
69
  useEffect(() => {
69
70
  let cancelled = false;
70
71
  void fetch(`${AUTH_BASE}/status`, { credentials: "same-origin" })
71
- .then((res) => res.json() as Promise<AuthStatus>)
72
+ .then((res) => {
73
+ if (!res.ok) throw new Error(`Authentication status failed (${res.status})`);
74
+ return res.json() as Promise<AuthStatus>;
75
+ })
72
76
  .then((status) => {
73
77
  if (cancelled) return;
74
78
  if (!status.enabled) setPhase("open");
@@ -108,6 +112,8 @@ export function AuthGate({ children, title, description }: AuthGateProps): React
108
112
  : "If an account exists for that email address, a verification code is on its way.",
109
113
  );
110
114
  setPhase("code");
115
+ } catch {
116
+ setNotice("Unable to request a verification code. Try again.");
111
117
  } finally {
112
118
  setBusy(false);
113
119
  }
@@ -135,6 +141,8 @@ export function AuthGate({ children, title, description }: AuthGateProps): React
135
141
  : "That verification code is incorrect or has expired.",
136
142
  );
137
143
  }
144
+ } catch {
145
+ setNotice("Unable to verify the code. Try again.");
138
146
  } finally {
139
147
  setBusy(false);
140
148
  }
@@ -125,6 +125,8 @@ export const EmailComposeView = ({
125
125
  const [showPreview, setShowPreview] = useState(false);
126
126
 
127
127
  const fileInput = useRef<HTMLInputElement>(null);
128
+ const onChangeRef = useRef(onChange);
129
+ onChangeRef.current = onChange;
128
130
  const ids = useId();
129
131
  const fieldId = (name: string) => `${ids}-${name}`;
130
132
 
@@ -149,8 +151,8 @@ export const EmailComposeView = ({
149
151
  }, [to, cc, bcc, subject, body, attachments]);
150
152
 
151
153
  useEffect(() => {
152
- onChange?.(buildMessage());
153
- }, [buildMessage, onChange]);
154
+ onChangeRef.current?.(buildMessage());
155
+ }, [buildMessage]);
154
156
 
155
157
  const addFiles = useCallback(async (files: FileList | null) => {
156
158
  if (!files || files.length === 0) return;