feat: Hide secrets on api and channels
This commit is contained in:
@@ -3,7 +3,14 @@
|
||||
import { useState } from "react";
|
||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import Link from "next/link";
|
||||
import { api, ChannelInput, ChannelType, NotificationChannel } from "@/lib/api";
|
||||
import {
|
||||
api,
|
||||
CHANNEL_SECRET_FIELDS,
|
||||
ChannelInput,
|
||||
ChannelType,
|
||||
NotificationChannel,
|
||||
REDACTED_SECRET,
|
||||
} from "@/lib/api";
|
||||
import { Badge, Button, Card, ConfirmDialog, friendlyMessage, useToast } from "@/components/ui";
|
||||
import { VulnAlertRulesCard } from "@/components/vulnerabilities/VulnAlertRulesCard";
|
||||
|
||||
@@ -67,17 +74,28 @@ function ChannelForm({ initial, onDone }: { initial?: NotificationChannel; onDon
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{CONFIG_FIELDS[type].map((field) => (
|
||||
<div key={field}>
|
||||
<label className={labelClass}>{field}</label>
|
||||
<input
|
||||
className={inputClass}
|
||||
type={field === "password" ? "password" : "text"}
|
||||
value={config[field] ?? ""}
|
||||
onChange={(e) => setConfig({ ...config, [field]: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
{CONFIG_FIELDS[type].map((field) => {
|
||||
// A secret comes back from the API as the sentinel, never as itself.
|
||||
// The field renders empty rather than showing bullets in a URL box, and
|
||||
// the sentinel is left sitting in state so an untouched save preserves
|
||||
// the credential. Typing replaces it; clearing the field back to empty
|
||||
// is how a credential is removed.
|
||||
const secret = CHANNEL_SECRET_FIELDS[type].includes(field);
|
||||
const value = config[field] ?? "";
|
||||
const unchanged = secret && value === REDACTED_SECRET;
|
||||
return (
|
||||
<div key={field}>
|
||||
<label className={labelClass}>{field}</label>
|
||||
<input
|
||||
className={inputClass}
|
||||
type={field === "password" ? "password" : "text"}
|
||||
value={unchanged ? "" : value}
|
||||
placeholder={unchanged ? "unchanged — type to replace" : undefined}
|
||||
onChange={(e) => setConfig({ ...config, [field]: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{error && <p className="text-sm text-danger">{(error as Error).message}</p>}
|
||||
<div className="flex gap-3">
|
||||
<Button type="submit" variant="primary" loading={isPending}>
|
||||
|
||||
Reference in New Issue
Block a user