mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
* [DeckShare] Open shared decks via links with a gated preview flow - Serialized url-chain dispatcher in IntentUrlParser; queue-drained urlChainFinished(bool) drives the startup auto-connect fallback - Open-shared-deck intent with sequential download state machine, 15s per-item timeout, partial-success offer, livable Cancel via ApplicationModal dlg_login_prompt interactive fallback - Preview dialog: download progress label, share vocab sweep, palette-highlight selection frame, Space/Enter keyboard toggle, NoFocus checkbox, double-click tile opens immediately - Confirm-before-server-migration with one-shot restore to the previous server on failed/cancelled chains (statusChanged settle deferral), hostname-only identity comparisons - Skip credential link when already connected; arrow-key navigation in FlowWidget; card glows use palette highlight - Address code-review M1-M4 and UI/UX QA blockers 1-2 * [DeckShare] End the open-shared-deck files with a trailing newline * [DeckShare] Forward a dependency's cancellation as the owner's own * [DeckShare] Let intent chains opt into the link sign-in dialog * [DeckShare] Track link-intent chains per-run so each can restore its own session * [Settings] Match a server on the exact host and port when adding it * [DeckShare] Confirm the share link's target server before opening a deck * [DeckShare] Reformat the link sign-in intent constructor * [DeckShare] Time the share-list round trip and backstop silently-destroyed intent chains * [Client] Drain a single-instance payload before its handlers read the socket again * [Client] Treat a busy single-instance primary as alive instead of stealing its socket * [DeckShare] Keep arrow-key navigation between flow items inside a scroll area * [Client] Skip the startup connection when a macOS URL launch owns the connection * [Client] Redact share secrets from activation URL logs * [Client] Make the link-connection gates port-aware and keyboard-safe Second-pass review notes for the shared-deck link flow (Cockatrice#7244): - FlowWidget arrow-key navigation is opt-in via addNavigableWidget, so combo/spin controls on the analytics flows keep their own arrow keys - isConnectedTo and the open-deck/join-game preconditions compare the configured server port alongside the host, so a same-host/different-port link cannot resolve its share token or game id on the wrong instance - the link sign-in dialog reuses an existing server entry's saved name instead of renaming it to the raw hostname - skipStartupAutoConnect is cleared once the launch chain connects, so a later mid-session declined link cannot fire the startup fallback - the plain-launch path of SingleInstanceManager no longer blocks on the primary's ACK - link- and server-supplied text is html-escaped in the confirm prompts and shared-deck preview so markup cannot spoof the shown messages --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
79 lines
3.2 KiB
C++
79 lines
3.2 KiB
C++
#include "intent_login.h"
|
|
|
|
#include "../../client/settings/cache_settings.h"
|
|
#include "../widgets/dialogs/dlg_login_prompt.h"
|
|
#include "libcockatrice/settings/servers_settings.h"
|
|
|
|
#include <QDialog>
|
|
|
|
IntentGetLoginCredentials::IntentGetLoginCredentials(ContextConnectToServer *_context,
|
|
bool _promptForMissingCredentials)
|
|
: Intent(), context(_context), promptForMissingCredentials(_promptForMissingCredentials)
|
|
{
|
|
}
|
|
|
|
bool IntentGetLoginCredentials::checkPrecondition() const
|
|
{
|
|
ServersSettings &servers = SettingsCache::instance().servers();
|
|
return servers.hasLoginData(context->hostname, context->port);
|
|
}
|
|
|
|
void IntentGetLoginCredentials::onPreconditionSatisfied()
|
|
{
|
|
ServersSettings &servers = SettingsCache::instance().servers();
|
|
const int index = servers.findServerIndex(context->hostname, context->port);
|
|
|
|
if (index >= 0) {
|
|
context->username = servers.getValue(QString("username%1").arg(index), "server", "server_details").toString();
|
|
context->password = servers.getValue(QString("password%1").arg(index), "server", "server_details").toString();
|
|
emitFinished();
|
|
} else {
|
|
emitFailed(tr("No saved credentials for this server"));
|
|
}
|
|
}
|
|
|
|
void IntentGetLoginCredentials::onPreconditionNotSatisfied()
|
|
{
|
|
// MainWindow::applyStartupDestination runs this intent on every launch for
|
|
// users whose startup tab is Server / Server Room; keep that path quiet, as
|
|
// it was before the link-driven sign-in dialog existed.
|
|
if (!promptForMissingCredentials) {
|
|
emitFailed(tr("No saved credentials for this server"));
|
|
return;
|
|
}
|
|
|
|
// No credentials saved for the target server: ask the user for them. They
|
|
// opt into saving them so later links to the same server connect directly.
|
|
const QString serverText = context->hostname + ":" + context->port;
|
|
DlgLoginPrompt dialog(serverText);
|
|
// ApplicationModal: the dialog has no parent (the intent is not a widget),
|
|
// so WindowModal would not actually block any other window.
|
|
dialog.setWindowModality(Qt::ApplicationModal);
|
|
|
|
if (dialog.exec() != QDialog::Accepted) {
|
|
emitCancelled();
|
|
return;
|
|
}
|
|
|
|
context->username = dialog.username();
|
|
context->password = dialog.password();
|
|
|
|
if (dialog.savePassword() && !context->username.isEmpty()) {
|
|
ServersSettings &servers = SettingsCache::instance().servers();
|
|
// The host may already be saved under a friendly name (e.g. a public-server
|
|
// list entry) with no credentials; reuse that name instead of overwriting
|
|
// it with the raw hostname when addNewServer updates the entry in place.
|
|
QString saveName = context->hostname;
|
|
const int existingIndex = servers.findServerIndex(context->hostname, context->port);
|
|
if (existingIndex >= 0) {
|
|
saveName =
|
|
servers.getValue(QString("saveName%1").arg(existingIndex), "server", "server_details").toString();
|
|
if (saveName.isEmpty()) {
|
|
saveName = context->hostname;
|
|
}
|
|
}
|
|
servers.addNewServer(saveName, context->hostname, context->port, context->username, context->password, true);
|
|
}
|
|
|
|
emitFinished();
|
|
}
|