mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
fix: can't set proxy for email account (IMAP) #326
This commit is contained in:
@@ -255,7 +255,6 @@ impl From<AccountV3> for AccountModel {
|
|||||||
created_at: value.created_at,
|
created_at: value.created_at,
|
||||||
updated_at: value.updated_at,
|
updated_at: value.updated_at,
|
||||||
created_by: value.created_by,
|
created_by: value.created_by,
|
||||||
use_proxy: value.use_proxy,
|
|
||||||
use_dangerous: value.use_dangerous,
|
use_dangerous: value.use_dangerous,
|
||||||
pgp_key: value.pgp_key,
|
pgp_key: value.pgp_key,
|
||||||
imap_quota_window: None,
|
imap_quota_window: None,
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ pub struct Account {
|
|||||||
pub created_at: i64,
|
pub created_at: i64,
|
||||||
pub updated_at: i64,
|
pub updated_at: i64,
|
||||||
pub created_by: u64, //user id
|
pub created_by: u64, //user id
|
||||||
pub use_proxy: Option<u64>,
|
|
||||||
pub use_dangerous: bool,
|
pub use_dangerous: bool,
|
||||||
pub pgp_key: Option<String>,
|
pub pgp_key: Option<String>,
|
||||||
pub imap_quota_bytes: Option<u64>,
|
pub imap_quota_bytes: Option<u64>,
|
||||||
@@ -345,7 +344,6 @@ impl Account {
|
|||||||
download_interval_min: request.download_interval_min,
|
download_interval_min: request.download_interval_min,
|
||||||
created_at: utc_now!(),
|
created_at: utc_now!(),
|
||||||
updated_at: utc_now!(),
|
updated_at: utc_now!(),
|
||||||
use_proxy: request.use_proxy,
|
|
||||||
use_dangerous: request.use_dangerous,
|
use_dangerous: request.use_dangerous,
|
||||||
pgp_key: request.pgp_key,
|
pgp_key: request.pgp_key,
|
||||||
created_by: user_id,
|
created_by: user_id,
|
||||||
@@ -657,10 +655,6 @@ impl Account {
|
|||||||
if let Some(max_email_size_bytes) = request.max_email_size_bytes {
|
if let Some(max_email_size_bytes) = request.max_email_size_bytes {
|
||||||
new.max_email_size_bytes = Some(max_email_size_bytes);
|
new.max_email_size_bytes = Some(max_email_size_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(use_proxy) = request.use_proxy {
|
|
||||||
new.use_proxy = Some(use_proxy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(old.account_type, AccountType::NoSync) {
|
if matches!(old.account_type, AccountType::NoSync) {
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ pub struct AccountCreateRequest {
|
|||||||
)]
|
)]
|
||||||
pub download_batch_size: Option<u32>,
|
pub download_batch_size: Option<u32>,
|
||||||
pub max_email_size_bytes: Option<u64>,
|
pub max_email_size_bytes: Option<u64>,
|
||||||
pub use_proxy: Option<u64>,
|
|
||||||
pub use_dangerous: bool,
|
pub use_dangerous: bool,
|
||||||
pub pgp_key: Option<String>,
|
pub pgp_key: Option<String>,
|
||||||
pub imap_quota_bytes: Option<u64>,
|
pub imap_quota_bytes: Option<u64>,
|
||||||
@@ -188,11 +187,6 @@ pub struct AccountUpdateRequest {
|
|||||||
)]
|
)]
|
||||||
pub download_batch_size: Option<u32>,
|
pub download_batch_size: Option<u32>,
|
||||||
pub max_email_size_bytes: Option<u64>,
|
pub max_email_size_bytes: Option<u64>,
|
||||||
/// Optional proxy ID for establishing the connection to external APIs (e.g., Gmail, Outlook).
|
|
||||||
/// - If `None` or not provided, the client will connect directly to the API server.
|
|
||||||
/// - If `Some(proxy_id)`, the client will use the pre-configured proxy with the given ID for API requests.
|
|
||||||
pub use_proxy: Option<u64>,
|
|
||||||
|
|
||||||
pub use_dangerous: Option<bool>,
|
pub use_dangerous: Option<bool>,
|
||||||
|
|
||||||
pub pgp_key: Option<String>,
|
pub pgp_key: Option<String>,
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ pub struct AccountResp {
|
|||||||
pub created_by: u64, //user id
|
pub created_by: u64, //user id
|
||||||
pub created_user_name: String,
|
pub created_user_name: String,
|
||||||
pub created_user_email: String,
|
pub created_user_email: String,
|
||||||
pub use_proxy: Option<u64>,
|
|
||||||
pub use_dangerous: bool,
|
pub use_dangerous: bool,
|
||||||
pub pgp_key: Option<String>,
|
pub pgp_key: Option<String>,
|
||||||
pub imap_quota_bytes: Option<u64>,
|
pub imap_quota_bytes: Option<u64>,
|
||||||
@@ -90,7 +89,6 @@ impl AccountResp {
|
|||||||
created_user_email: user
|
created_user_email: user
|
||||||
.map(|u| u.email.clone())
|
.map(|u| u.email.clone())
|
||||||
.unwrap_or_else(|| "N/A".to_string()),
|
.unwrap_or_else(|| "N/A".to_string()),
|
||||||
use_proxy: account.use_proxy,
|
|
||||||
use_dangerous: account.use_dangerous,
|
use_dangerous: account.use_dangerous,
|
||||||
pgp_key: account.pgp_key,
|
pgp_key: account.pgp_key,
|
||||||
imap_quota_bytes: account.imap_quota_bytes,
|
imap_quota_bytes: account.imap_quota_bytes,
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ export interface AccountModel {
|
|||||||
created_user_email: string;
|
created_user_email: string;
|
||||||
created_at: number;
|
created_at: number;
|
||||||
updated_at: number;
|
updated_at: number;
|
||||||
use_proxy?: number;
|
|
||||||
use_dangerous: boolean;
|
use_dangerous: boolean;
|
||||||
pgp_key?: string;
|
pgp_key?: string;
|
||||||
imap_quota_window?: QuotaWindow;
|
imap_quota_window?: QuotaWindow;
|
||||||
|
|||||||
@@ -111,12 +111,14 @@ export function AccountNewPage() {
|
|||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
(data: AccountFormValues) => {
|
(data: AccountFormValues) => {
|
||||||
|
const { use_proxy, ...imapRest } = data.imap;
|
||||||
createMutation.mutate({
|
createMutation.mutate({
|
||||||
email: data.email,
|
email: data.email,
|
||||||
account_name: data.account_name,
|
account_name: data.account_name,
|
||||||
login_name: data.login_name,
|
login_name: data.login_name,
|
||||||
imap: {
|
imap: {
|
||||||
...data.imap,
|
...imapRest,
|
||||||
|
use_proxy,
|
||||||
auth: {
|
auth: {
|
||||||
...data.imap.auth,
|
...data.imap.auth,
|
||||||
password: data.imap.auth.auth_type === 'OAuth2' ? undefined : data.imap.auth.password,
|
password: data.imap.auth.auth_type === 'OAuth2' ? undefined : data.imap.auth.password,
|
||||||
|
|||||||
@@ -44,15 +44,12 @@ const emptyImap = {
|
|||||||
port: 0,
|
port: 0,
|
||||||
encryption: "None" as const,
|
encryption: "None" as const,
|
||||||
auth: { auth_type: "Password" as const, password: undefined },
|
auth: { auth_type: "Password" as const, password: undefined },
|
||||||
use_proxy: undefined,
|
use_proxy: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapAccountToFormValues(account: AccountModel): AccountFormValues {
|
function mapAccountToFormValues(account: AccountModel): AccountFormValues {
|
||||||
const imap = { ...(account.imap ?? emptyImap) };
|
const imap = { ...(account.imap ?? emptyImap) };
|
||||||
imap.auth = { ...imap.auth, password: undefined };
|
imap.auth = { ...imap.auth, password: undefined };
|
||||||
if ((imap as any).use_proxy === null) {
|
|
||||||
(imap as any).use_proxy = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
account_name: account.account_name ?? undefined,
|
account_name: account.account_name ?? undefined,
|
||||||
@@ -137,12 +134,14 @@ export function AccountSettingsPage({ accountId }: AccountSettingsPageProps) {
|
|||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
(data: AccountFormValues) => {
|
(data: AccountFormValues) => {
|
||||||
|
const { use_proxy, ...imapRest } = data.imap;
|
||||||
const payload: Record<string, any> = {
|
const payload: Record<string, any> = {
|
||||||
email: data.email,
|
email: data.email,
|
||||||
account_name: data.account_name,
|
account_name: data.account_name,
|
||||||
login_name: data.login_name,
|
login_name: data.login_name,
|
||||||
imap: {
|
imap: {
|
||||||
...data.imap,
|
...imapRest,
|
||||||
|
use_proxy,
|
||||||
auth: {
|
auth: {
|
||||||
...data.imap.auth,
|
...data.imap.auth,
|
||||||
password: data.imap.auth.auth_type === 'OAuth2'
|
password: data.imap.auth.auth_type === 'OAuth2'
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { PasswordInput } from "@/components/password-input";
|
import { PasswordInput } from "@/components/password-input";
|
||||||
import { AccountFormValues } from "./schema";
|
import { AccountFormValues } from "./schema";
|
||||||
|
import useProxyList from "@/hooks/use-proxy";
|
||||||
|
|
||||||
interface TabServerProps {
|
interface TabServerProps {
|
||||||
isEdit?: boolean;
|
isEdit?: boolean;
|
||||||
@@ -46,6 +47,7 @@ export function TabServer({ isEdit }: TabServerProps) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { control, watch } = useFormContext<AccountFormValues>();
|
const { control, watch } = useFormContext<AccountFormValues>();
|
||||||
const authType = watch('imap.auth.auth_type');
|
const authType = watch('imap.auth.auth_type');
|
||||||
|
const { proxyOptions } = useProxyList();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@@ -161,6 +163,38 @@ export function TabServer({ isEdit }: TabServerProps) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={control}
|
||||||
|
name="imap.use_proxy"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('accounts.useProxyOptional')}</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(v) => field.onChange(v === 'none' ? undefined : Number(v))}
|
||||||
|
defaultValue={field.value?.toString()}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder={t('accounts.selectProxy')}/>
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem key="none" value="none">{t('accounts.useNoProxy')}</SelectItem>
|
||||||
|
{proxyOptions.map((opt) => (
|
||||||
|
<SelectItem key={opt.value} value={opt.value}>
|
||||||
|
<span className="max-w-[280px] truncate block" title={opt.label}>
|
||||||
|
{opt.label}
|
||||||
|
</span>
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormDescription>{t('accounts.imapProxy')}</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={control}
|
control={control}
|
||||||
name="use_dangerous"
|
name="use_dangerous"
|
||||||
|
|||||||
Reference in New Issue
Block a user