diff --git a/Outpost/Features/Account/SettingsView.swift b/Outpost/Features/Account/SettingsView.swift index 5d0e539..42eb31f 100644 --- a/Outpost/Features/Account/SettingsView.swift +++ b/Outpost/Features/Account/SettingsView.swift @@ -53,6 +53,7 @@ struct SettingsView: View { @State private var didCopyRevealedKey = false @State private var apiKeyPendingDeletion: OutlineAPIKey? @State private var deletingApiKeyId: String? + @State private var isShowingApiKeyWebOnlyNotice = false /// Full Local Sync and cache-clearing both need a real connection to be /// safe — clearing while offline (or letting Full Local Sync think it @@ -772,8 +773,14 @@ struct SettingsView: View { Text("Personal keys") .font(.headline) Spacer() - Button("New API Key…") { isShowingCreateApiKey = true } - .disabled(!isEffectivelyOnline) + // TODO: apiKeys.create needs Outline's cookie+CSRF web + // session, not this app's Bearer-token auth — confirmed + // this app's requests to it don't work. Swap this back to + // `isShowingCreateApiKey = true` (the real create sheet + // below is fully built and untouched) once there's a + // supported native auth path, or Outline adds Bearer + // support for this endpoint. + Button("New API Key…") { isShowingApiKeyWebOnlyNotice = true } } .frame(maxWidth: 480) @@ -807,6 +814,11 @@ struct SettingsView: View { Text("Any scripts or integrations using \"\(name)\" will stop working immediately.") } } + .alert("Manage API Keys on the Web", isPresented: $isShowingApiKeyWebOnlyNotice) { + Button("OK") {} + } message: { + Text("Creating and deleting personal API keys currently requires Outline's web app, the same way Passkeys does — this app can only display your existing keys for now. We may add this here in the future if Outline supports it or we add the right kind of authentication.") + } } /// Shown exactly once, immediately after creation — Outline never @@ -967,19 +979,28 @@ struct SettingsView: View { if deletingApiKeyId == key.id { ProgressView().controlSize(.small) } else { + // TODO: apiKeys.delete — same web-session-only limitation + // as create above, see that comment. Swap back to + // `apiKeyPendingDeletion = key` (the real confirmation + // dialog + deleteApiKey(_:) below are fully built and + // untouched) once native auth can actually call it. Button { - apiKeyPendingDeletion = key + isShowingApiKeyWebOnlyNotice = true } label: { Image(systemName: "trash") } .buttonStyle(.plain) .foregroundStyle(.red) - .disabled(!isEffectivelyOnline) } } .padding(.vertical, 8) } + // TODO: not currently reachable from the UI — apiKeys.create needs + // Outline's cookie+CSRF web session, confirmed this app's Bearer-token + // requests to it don't work. Kept intact (and covered by OutlineKit + // tests) for when native auth can support it; see the "New API Key…" + // button's own TODO for the reconnect point. private func createApiKey() async { guard let apiClient = session.apiClient else { return } let trimmedName = newApiKeyName.trimmingCharacters(in: .whitespacesAndNewlines) @@ -1007,6 +1028,9 @@ struct SettingsView: View { } } + // TODO: not currently reachable from the UI — same apiKeys.delete + // web-session-only limitation as createApiKey() above. Kept intact + // for the same reason; see the trash button's own TODO. private func deleteApiKey(_ key: OutlineAPIKey) async { guard let apiClient = session.apiClient else { return } apiKeyPendingDeletion = nil