Skip to content

Commit feda69f

Browse files
authored
Refactor gmail into gmail-auth and gmail-importer (#1971)
* Refactor gmail into gmail-auth and gmail-importer. gmail-importer expects to be linked to a gmail-auth. This allows authenticating a single time in a space and having multiple gmail-importers that use it. * deno fmt. * Delete the legacy gmail.tsx
1 parent 7bb002a commit feda69f

File tree

2 files changed

+138
-17
lines changed

2 files changed

+138
-17
lines changed

recipes/gmail-auth.tsx

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/// <cts-enable />
2+
import { Default, NAME, recipe, UI } from "commontools";
3+
4+
type CFC<T, C extends string> = T;
5+
type Secret<T> = CFC<T, "secret">;
6+
7+
// Auth data structure for Google OAuth tokens
8+
export type Auth = {
9+
token: Default<Secret<string>, "">;
10+
tokenType: Default<string, "">;
11+
scope: Default<string[], []>;
12+
expiresIn: Default<number, 0>;
13+
expiresAt: Default<number, 0>;
14+
refreshToken: Default<Secret<string>, "">;
15+
user: Default<{
16+
email: string;
17+
name: string;
18+
picture: string;
19+
}, { email: ""; name: ""; picture: "" }>;
20+
};
21+
22+
interface Input {
23+
auth: Default<Auth, {
24+
token: "";
25+
tokenType: "";
26+
scope: [];
27+
expiresIn: 0;
28+
expiresAt: 0;
29+
refreshToken: "";
30+
user: { email: ""; name: ""; picture: "" };
31+
}>;
32+
}
33+
34+
interface Output {
35+
auth: Auth;
36+
}
37+
38+
export default recipe<Input, Output>(
39+
"Gmail Auth",
40+
({ auth }) => {
41+
return {
42+
[NAME]: "Gmail Auth",
43+
[UI]: (
44+
<div
45+
style={{
46+
display: "flex",
47+
flexDirection: "column",
48+
gap: "20px",
49+
padding: "25px",
50+
maxWidth: "600px",
51+
}}
52+
>
53+
<h2 style={{ fontSize: "24px", fontWeight: "bold", margin: "0" }}>
54+
Google OAuth Authentication
55+
</h2>
56+
57+
<div
58+
style={{
59+
padding: "20px",
60+
backgroundColor: "#f8f9fa",
61+
borderRadius: "8px",
62+
border: "1px solid #e0e0e0",
63+
}}
64+
>
65+
<h3 style={{ fontSize: "16px", marginTop: "0" }}>
66+
Status:{" "}
67+
{auth?.user?.email ? "✅ Authenticated" : "⚠️ Not Authenticated"}
68+
</h3>
69+
70+
{auth?.user?.email
71+
? (
72+
<div>
73+
<p style={{ margin: "8px 0" }}>
74+
<strong>Email:</strong> {auth.user.email}
75+
</p>
76+
<p style={{ margin: "8px 0" }}>
77+
<strong>Name:</strong> {auth.user.name}
78+
</p>
79+
</div>
80+
)
81+
: (
82+
<p style={{ color: "#666" }}>
83+
Click the button below to authenticate with Google
84+
</p>
85+
)}
86+
</div>
87+
88+
<common-google-oauth
89+
$auth={auth}
90+
scopes={[
91+
"email",
92+
"profile",
93+
"https://www.googleapis.com/auth/gmail.readonly",
94+
]}
95+
/>
96+
97+
<div
98+
style={{
99+
padding: "15px",
100+
backgroundColor: "#e3f2fd",
101+
borderRadius: "8px",
102+
fontSize: "14px",
103+
}}
104+
>
105+
<strong>💡 Usage:</strong>{" "}
106+
This charm provides Google OAuth authentication. Link its{" "}
107+
<code>auth</code> output to any gmail importer charm's{" "}
108+
<code>auth</code> input.
109+
</div>
110+
</div>
111+
),
112+
auth,
113+
};
114+
},
115+
);

recipes/gmail.tsx renamed to recipes/gmail-importer.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Secret<T> = CFC<T, "secret">;
1818
type Confidential<T> = CFC<T, "confidential">;
1919

2020
// This is used by the various Google tokens created with tokenToAuthData
21-
type Auth = {
21+
export type Auth = {
2222
token: Default<Secret<string>, "">;
2323
tokenType: Default<string, "">;
2424
scope: Default<string[], []>;
@@ -778,9 +778,6 @@ export async function process(
778778

779779
if (emails.length > 0) {
780780
console.log(`Adding ${emails.length} new emails`);
781-
// emails.forEach((email) => {
782-
// email[ID] = email.id;
783-
// });
784781
allNewEmails.push(...emails);
785782
}
786783
} catch (error: any) {
@@ -819,7 +816,7 @@ export default recipe<{
819816
}>;
820817
auth: Auth;
821818
}>(
822-
"gmail",
819+
"gmail-importer",
823820
({ settings, auth }) => {
824821
const emails = cell<Confidential<Email[]>>([]);
825822

@@ -841,13 +838,29 @@ export default recipe<{
841838
}}
842839
>
843840
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>
844-
{auth?.user?.email}
841+
Gmail Importer
845842
</h2>
846-
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>
843+
844+
<div
845+
style={{
846+
padding: "15px",
847+
backgroundColor: auth?.user?.email ? "#d4edda" : "#f8d7da",
848+
borderRadius: "8px",
849+
border: `1px solid ${auth?.user?.email ? "#c3e6cb" : "#f5c6cb"}`,
850+
}}
851+
>
852+
<strong>Auth Status:</strong> {auth?.user?.email
853+
? `✅ Authenticated as ${auth.user.email}`
854+
: "❌ Not authenticated - Please link to a gmail-auth charm"}
855+
</div>
856+
857+
<h3 style={{ fontSize: "18px", fontWeight: "bold" }}>
847858
Imported email count: {derive(emails, (emails) => emails.length)}
848-
</h2>
859+
</h3>
849860

850-
<h2>historyId: {settings.historyId}</h2>
861+
<div style={{ fontSize: "14px", color: "#666" }}>
862+
historyId: {settings.historyId || "none"}
863+
</div>
851864

852865
<common-hstack gap="sm">
853866
<common-vstack gap="sm">
@@ -884,14 +897,7 @@ export default recipe<{
884897
</ct-button>
885898
</common-vstack>
886899
</common-hstack>
887-
<common-google-oauth
888-
$auth={auth}
889-
scopes={[
890-
"email",
891-
"profile",
892-
"https://www.googleapis.com/auth/gmail.readonly",
893-
]}
894-
/>
900+
895901
<div>
896902
<table>
897903
<thead>

0 commit comments

Comments
 (0)