mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[DeckShare] Open shared decks via links with a gated preview flow (#7244)
* [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>
This commit is contained in:
parent
ba2900dcb9
commit
8ca749c07d
29 changed files with 1666 additions and 86 deletions
|
|
@ -171,7 +171,12 @@ void ServersSettings::addNewServer(const QString &saveName,
|
|||
bool savePassword,
|
||||
const QString &site)
|
||||
{
|
||||
if (updateExistingServer(saveName, serv, port, username, password, savePassword, site)) {
|
||||
// Match the exact host-plus-port server the caller is adding, so a link or
|
||||
// public-server list entry cannot clobber the port (and credentials) of an
|
||||
// unrelated entry that happens to share the same hostname.
|
||||
const int existingIndex = findServerIndex(serv, port);
|
||||
if (existingIndex >= 0) {
|
||||
updateServerFields(existingIndex, saveName, username, password, savePassword, site);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -271,22 +276,7 @@ bool ServersSettings::updateExistingServer(QString saveName,
|
|||
for (int i = 0; i <= size; ++i) {
|
||||
if (serv == getValue(QString("server%1").arg(i), "server", "server_details").toString()) {
|
||||
setValue(port, QString("port%1").arg(i), "server", "server_details");
|
||||
if (!username.isEmpty()) {
|
||||
setValue(username, QString("username%1").arg(i), "server", "server_details");
|
||||
}
|
||||
|
||||
if (savePassword && !password.isEmpty()) {
|
||||
setValue(password, QString("password%1").arg(i), "server", "server_details");
|
||||
} else {
|
||||
setValue(QString(), QString("password%1").arg(i), "server", "server_details");
|
||||
}
|
||||
|
||||
if (!site.isEmpty()) {
|
||||
setValue(site, QString("site%1").arg(i), "server", "server_details");
|
||||
}
|
||||
|
||||
setValue(savePassword, QString("savePassword%1").arg(i), "server", "server_details");
|
||||
setValue(saveName, QString("saveName%1").arg(i), "server", "server_details");
|
||||
updateServerFields(i, saveName, username, password, savePassword, site);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -294,6 +284,31 @@ bool ServersSettings::updateExistingServer(QString saveName,
|
|||
return false;
|
||||
}
|
||||
|
||||
void ServersSettings::updateServerFields(int index,
|
||||
const QString &saveName,
|
||||
const QString &username,
|
||||
const QString &password,
|
||||
bool savePassword,
|
||||
const QString &site)
|
||||
{
|
||||
if (!username.isEmpty()) {
|
||||
setValue(username, QString("username%1").arg(index), "server", "server_details");
|
||||
}
|
||||
|
||||
if (savePassword && !password.isEmpty()) {
|
||||
setValue(password, QString("password%1").arg(index), "server", "server_details");
|
||||
} else {
|
||||
setValue(QString(), QString("password%1").arg(index), "server", "server_details");
|
||||
}
|
||||
|
||||
if (!site.isEmpty()) {
|
||||
setValue(site, QString("site%1").arg(index), "server", "server_details");
|
||||
}
|
||||
|
||||
setValue(savePassword, QString("savePassword%1").arg(index), "server", "server_details");
|
||||
setValue(saveName, QString("saveName%1").arg(index), "server", "server_details");
|
||||
}
|
||||
|
||||
int ServersSettings::findServerIndex(const QString &host, const QString &port) const
|
||||
{
|
||||
int size = getValue("totalServers", "server", "server_details").toInt();
|
||||
|
|
@ -310,6 +325,21 @@ int ServersSettings::findServerIndex(const QString &host, const QString &port) c
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ServersSettings::findHostIndex(const QString &host) const
|
||||
{
|
||||
int size = getValue("totalServers", "server", "server_details").toInt();
|
||||
|
||||
for (int i = 0; i <= size; ++i) {
|
||||
QString storedHost = getValue(QString("server%1").arg(i), "server", "server_details").toString();
|
||||
|
||||
if (storedHost.compare(host, Qt::CaseInsensitive) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ServersSettings::hasUsername(const QString &host, const QString &port) const
|
||||
{
|
||||
int index = findServerIndex(host, port);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue