Skip to content

Commit dc71b06

Browse files
authored
Add support for new SMTP config schema (#382)
1 parent 931eafe commit dc71b06

File tree

6 files changed

+1227
-281
lines changed

6 files changed

+1227
-281
lines changed

shared/studio/tabs/auth/authAdmin.module.scss

+213-3
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@
120120
}
121121
}
122122

123+
.titleWrapper {
124+
display: flex;
125+
align-items: center;
126+
min-height: 36px;
127+
128+
h2 {
129+
margin-right: 24px;
130+
}
131+
132+
button {
133+
margin-left: auto;
134+
}
135+
}
136+
123137
.cardList {
124138
display: flex;
125139
flex-direction: column;
@@ -241,19 +255,32 @@
241255

242256
.grid {
243257
display: grid;
244-
grid-auto-flow: column;
245-
grid-template-rows: repeat(calc(var(--itemCount) / var(--colCount)), auto);
246-
gap: 4px;
258+
grid-template-columns: repeat(var(--colCount), auto);
259+
gap: 6px 24px;
260+
261+
> div {
262+
display: flex;
263+
flex-direction: column;
264+
gap: 6px;
265+
}
247266

248267
label {
249268
font-family: "Roboto Mono Variable", monospace;
250269
font-weight: 425;
251270
font-size: 13px;
271+
align-items: start;
272+
height: auto;
273+
line-height: 20px;
274+
padding: 6px 0;
252275
}
253276
}
254277

255278
@media (max-width: 960px) {
256279
--colCount: 2;
280+
281+
.grid > div:nth-child(2) {
282+
grid-row: span 2;
283+
}
257284
}
258285
@media (max-width: 512px) {
259286
--colCount: 1;
@@ -457,6 +484,18 @@
457484

458485
.securitySelect {
459486
font-family: "Roboto Mono Variable", monospace;
487+
488+
&[data-disabled="true"] {
489+
background: #f7f7f7;
490+
border-color: var(--Grey90);
491+
box-shadow: none;
492+
opacity: 1;
493+
494+
@include darkTheme {
495+
background: #464646;
496+
border-color: #4d4d4d;
497+
}
498+
}
460499
}
461500

462501
.redirectUrlsLabel {
@@ -475,6 +514,177 @@
475514
resize: vertical;
476515
}
477516

517+
.newDraftSMTPProvider {
518+
display: flex;
519+
flex-direction: column;
520+
width: 100%;
521+
522+
.configGrid {
523+
margin-top: 0;
524+
}
525+
526+
.buttons {
527+
display: flex;
528+
gap: 16px;
529+
justify-content: flex-end;
530+
margin-top: 24px;
531+
flex-direction: row;
532+
}
533+
}
534+
535+
.emailProvidersUpdating {
536+
opacity: 0.7;
537+
pointer-events: none;
538+
}
539+
540+
.emailProviderCard {
541+
.details {
542+
display: flex;
543+
flex-direction: column;
544+
color: var(--main_text_color);
545+
line-height: 22px;
546+
547+
.name {
548+
font-weight: 500;
549+
}
550+
551+
.senderhost {
552+
color: var(--tertiary_text_color);
553+
554+
span {
555+
font-size: 11px;
556+
margin: 0 6px;
557+
opacity: 0.5;
558+
}
559+
}
560+
}
561+
562+
.selectCurrentProvider {
563+
width: 32px;
564+
height: 32px;
565+
stroke-width: 1px;
566+
stroke: var(--Grey75);
567+
cursor: pointer;
568+
flex-shrink: 0;
569+
570+
&.selected {
571+
fill: #a565cd;
572+
stroke: #9c56b4 !important;
573+
}
574+
575+
@include darkTheme {
576+
stroke: var(--Grey40);
577+
}
578+
}
579+
580+
.updatingSpinner {
581+
color: var(--Grey50);
582+
width: 32px;
583+
flex-shrink: 0;
584+
}
585+
586+
.buttons {
587+
display: flex;
588+
gap: 16px;
589+
justify-content: flex-end;
590+
flex-direction: row;
591+
padding: 4px 16px 16px 16px;
592+
}
593+
}
594+
595+
.expandedEmailProviderConfig {
596+
margin: -2px 12px 12px 12px;
597+
background: var(--Grey97);
598+
border-radius: 8px;
599+
border: 1px solid var(--Grey93);
600+
601+
@include darkTheme {
602+
background: var(--Grey16);
603+
border-color: var(--Grey25);
604+
}
605+
606+
.configGrid {
607+
margin-top: 20px;
608+
margin-bottom: 12px;
609+
610+
@include isMobile {
611+
margin: 16px;
612+
}
613+
}
614+
}
615+
616+
.passwordWarning {
617+
display: flex;
618+
align-items: flex-start;
619+
gap: 4px;
620+
color: var(--secondary_text_color);
621+
font-size: 14px;
622+
font-style: normal;
623+
font-weight: 400;
624+
line-height: 20px;
625+
background: #f7e9c8;
626+
border-radius: 8px;
627+
border: 1px solid #c1a970;
628+
color: #7b6226;
629+
padding: 8px 12px 10px 12px;
630+
margin: 0 12px;
631+
margin-bottom: 0px;
632+
margin-bottom: 12px;
633+
634+
> div {
635+
margin-top: 2px;
636+
637+
> span {
638+
font-weight: 500;
639+
}
640+
}
641+
642+
svg {
643+
flex-shrink: 0;
644+
}
645+
646+
@include darkTheme {
647+
background: #453d2c;
648+
border: 1px solid #72623b;
649+
color: #d1bd8f;
650+
}
651+
}
652+
653+
.emailProviderWarning {
654+
position: relative;
655+
padding: 12px 20px;
656+
padding-left: 48px;
657+
background: #f7e9c8;
658+
border-radius: 8px;
659+
border: 1px solid #c1a970;
660+
color: #7b6226;
661+
font-weight: 450;
662+
line-height: 20px;
663+
margin-top: 16px;
664+
665+
& > svg {
666+
position: absolute;
667+
left: 16px;
668+
top: 14px;
669+
}
670+
671+
& > span {
672+
font-weight: 500;
673+
}
674+
675+
.link {
676+
font-weight: inherit;
677+
cursor: pointer;
678+
text-decoration: underline;
679+
}
680+
681+
@include darkTheme {
682+
background: #453d2c;
683+
border: 1px solid #72623b;
684+
color: #d1bd8f;
685+
}
686+
}
687+
478688
.docsNote {
479689
display: flex;
480690
align-items: flex-start;

shared/studio/tabs/auth/providers.tsx

+70-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from "@edgedb/common/newui";
3232

3333
import styles from "./authAdmin.module.scss";
34-
import {StickyBottomBar} from "./shared";
34+
import {EmailProviderWarning, StickyBottomBar} from "./shared";
3535
import {Theme, useTheme} from "@edgedb/common/hooks/useTheme";
3636
import {AppConfigForm} from "./config";
3737
import {
@@ -50,11 +50,75 @@ export const ProvidersTab = observer(function ProvidersTab() {
5050
{state.providers ? (
5151
<>
5252
{state.providers.length ? (
53-
<div className={styles.cardList}>
54-
{state.providers.map((provider) => (
55-
<ProviderCard key={provider.name} provider={provider} />
56-
))}
57-
</div>
53+
<>
54+
{state.emailProviderWarnings.verificationNoSmtp ? (
55+
<EmailProviderWarning>
56+
You have auth providers requiring email verification enabled,
57+
but no method for verifying emails is configured.
58+
<br />
59+
<span
60+
className={styles.link}
61+
onClick={() => state.setSelectedTab("smtp")}
62+
>
63+
Enable an SMTP provider
64+
</span>{" "}
65+
or{" "}
66+
<span
67+
className={styles.link}
68+
onClick={() => state.setSelectedTab("webhooks")}
69+
>
70+
create a webhook
71+
</span>{" "}
72+
to handle email verification.
73+
</EmailProviderWarning>
74+
) : state.emailProviderWarnings.passwordNoReset ? (
75+
<EmailProviderWarning>
76+
You have the 'Email + Password' auth provider enabled, but no
77+
method for sending password resets is configured.
78+
<br />
79+
<span
80+
className={styles.link}
81+
onClick={() => state.setSelectedTab("smtp")}
82+
>
83+
Enable an SMTP provider
84+
</span>{" "}
85+
or{" "}
86+
<span
87+
className={styles.link}
88+
onClick={() => state.setSelectedTab("webhooks")}
89+
>
90+
create a webhook
91+
</span>{" "}
92+
to handle password resets.
93+
</EmailProviderWarning>
94+
) : state.emailProviderWarnings.magicLinkNoMethods ? (
95+
<EmailProviderWarning>
96+
You have the 'Magic Link' auth provider enabled, but no
97+
method for sending magic links is configured.
98+
<br />
99+
<span
100+
className={styles.link}
101+
onClick={() => state.setSelectedTab("smtp")}
102+
>
103+
Enable an SMTP provider
104+
</span>{" "}
105+
or{" "}
106+
<span
107+
className={styles.link}
108+
onClick={() => state.setSelectedTab("webhooks")}
109+
>
110+
create a webhook
111+
</span>{" "}
112+
to handle magic links.
113+
</EmailProviderWarning>
114+
) : null}
115+
116+
<div className={styles.cardList}>
117+
{state.providers.map((provider) => (
118+
<ProviderCard key={provider.name} provider={provider} />
119+
))}
120+
</div>
121+
</>
58122
) : null}
59123

60124
{state.draftProviderConfig ? (

shared/studio/tabs/auth/shared.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {observer} from "mobx-react-lite";
22

33
import cn from "@edgedb/common/utils/classNames";
44

5-
import {Button} from "@edgedb/common/newui";
5+
import {Button, WarningIcon} from "@edgedb/common/newui";
66

77
import {AbstractDraftConfig} from "./state";
88

@@ -53,3 +53,12 @@ export const StickyFormControls = observer(function StickyFormControls({
5353
export const InputSkeleton = () => (
5454
<LoadingSkeleton className={styles.inputSkeleton} />
5555
);
56+
57+
export function EmailProviderWarning({children}: PropsWithChildren<{}>) {
58+
return (
59+
<div className={styles.emailProviderWarning}>
60+
<WarningIcon />
61+
<span>Warning:</span> {children}
62+
</div>
63+
);
64+
}

0 commit comments

Comments
 (0)