feat: Manage API tokens from settings
A card in the Access group beside Members and single sign-on rather than a new nav entry — /settings/instance was folded back in for exactly this reason. The plaintext is shown once in a well block and never again. Tokens outside a newly tightened lifetime policy are flagged rather than broken, because the policy governs issuance, not existing credentials.
This commit is contained in:
@@ -10,6 +10,7 @@ import { Field } from "@/components/settings/Field";
|
||||
import { Group } from "@/components/settings/Group";
|
||||
import { SectionCard } from "@/components/settings/SectionCard";
|
||||
import { MembersCard } from "@/components/settings/MembersCard";
|
||||
import { ApiTokensCard } from "@/components/settings/ApiTokensCard";
|
||||
import { AuthProvidersCard } from "@/components/settings/AuthProvidersCard";
|
||||
|
||||
const numberInputClass =
|
||||
@@ -144,6 +145,7 @@ export default function SettingsPage() {
|
||||
const [thresholdMinutes, setThresholdMinutes] = useState(5);
|
||||
const [logRetentionDays, setLogRetentionDays] = useState(30);
|
||||
const [offlineChannelIds, setOfflineChannelIds] = useState<string[]>([]);
|
||||
const [apiTokenMaxDays, setApiTokenMaxDays] = useState(0);
|
||||
const toast = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -151,6 +153,7 @@ export default function SettingsPage() {
|
||||
setThresholdMinutes(settings.alerts.offline_threshold_minutes || 5);
|
||||
setLogRetentionDays(settings.workflow_log_retention_days ?? 30);
|
||||
setOfflineChannelIds(settings.alerts.offline_channel_ids ?? []);
|
||||
setApiTokenMaxDays(settings.api_token_max_days ?? 0);
|
||||
}, [settings]);
|
||||
|
||||
// The one place the in-progress form is turned into a payload. Both the
|
||||
@@ -163,6 +166,7 @@ export default function SettingsPage() {
|
||||
offline_channel_ids: offlineChannelIds,
|
||||
},
|
||||
workflow_log_retention_days: logRetentionDays,
|
||||
api_token_max_days: apiTokenMaxDays,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -220,6 +224,7 @@ export default function SettingsPage() {
|
||||
<div className="space-y-10">
|
||||
<Group label="Access">
|
||||
<MembersCard />
|
||||
<ApiTokensCard />
|
||||
<AuthProvidersCard
|
||||
localLoginEnabled={settings?.local_login_enabled ?? true}
|
||||
onLocalLoginChange={(v) => {
|
||||
@@ -291,6 +296,15 @@ export default function SettingsPage() {
|
||||
<Field label="Log retention (days)" hint="0 = keep forever. Applies to per-run step output logs.">
|
||||
<input type="number" min={0} value={logRetentionDays} onChange={(e) => setLogRetentionDays(Number(e.target.value))} className={numberInputClass} />
|
||||
</Field>
|
||||
|
||||
<div className="mt-6">
|
||||
<Field
|
||||
label="Maximum API token lifetime (days)"
|
||||
hint="0 means no cap, and tokens may be created with no expiry. Changing this affects new tokens only."
|
||||
>
|
||||
<input type="number" min={0} value={apiTokenMaxDays} onChange={(e) => setApiTokenMaxDays(Number(e.target.value))} className={numberInputClass} />
|
||||
</Field>
|
||||
</div>
|
||||
</SectionCard>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user