| 160 | } |
| 161 | |
| 162 | void OAuthService::startAuth(const QString &provider, const QString &tokenPath) |
| 163 | { |
| 164 | cancel(); // clean up any previous attempt |
| 165 | |
| 166 | m_provider = provider; |
| 167 | m_tokenPath = tokenPath; |
| 168 | |
| 169 | // Generate PKCE values (used for Google Drive) |
| 170 | m_state = generateRandomString(32); |
| 171 | m_codeVerifier = generateRandomString(64); |
| 172 | QString codeChallenge = computeCodeChallenge(m_codeVerifier); |
| 173 | |
| 174 | // OneDrive uses rclone's fixed port 53682, Google Drive uses dynamic port |
| 175 | m_server = new QTcpServer(this); |
| 176 | |
| 177 | if (provider == "onedrive") { |
| 178 | // rclone's Azure AD app only has http://localhost:53682/ registered |
| 179 | if (!m_server->listen(QHostAddress::LocalHost, 53682)) { |
| 180 | emit authFailed(provider, "Failed to start local HTTP server on port 53682: " + m_server->errorString()); |
| 181 | delete m_server; |
| 182 | m_server = nullptr; |
| 183 | return; |
| 184 | } |
| 185 | m_redirectUri = "http://localhost:53682/"; |
| 186 | } else if (provider == "gdrive") { |
| 187 | // Fixed port for Google Drive, ugh |
| 188 | if (!m_server->listen(QHostAddress::LocalHost, 53692)) { |
| 189 | emit authFailed(provider, "Failed to start local HTTP server on port 53692: " + m_server->errorString()); |
| 190 | delete m_server; |
| 191 | m_server = nullptr; |
| 192 | return; |
| 193 | } |
| 194 | m_redirectUri = "http://localhost:53692/callback"; |
| 195 | } else { |
| 196 | // Other providers use dynamic port |
| 197 | if (!m_server->listen(QHostAddress::LocalHost, 0)) { |
| 198 | emit authFailed(provider, "Failed to start local HTTP server: " + m_server->errorString()); |
| 199 | delete m_server; |
| 200 | m_server = nullptr; |
| 201 | return; |
| 202 | } |
| 203 | m_redirectUri = QString("http://localhost:%1/callback").arg(m_server->serverPort()); |
| 204 | } |
| 205 | |
| 206 | m_port = m_server->serverPort(); |
| 207 | connect(m_server, &QTcpServer::newConnection, this, &OAuthService::onNewConnection); |
| 208 | |
| 209 | emit statusMessage(QString("Listening on %1").arg(m_redirectUri)); |
| 210 | |
| 211 | // Build auth URL |
| 212 | QUrl authUrl; |
| 213 | QUrlQuery params; |
| 214 | |
| 215 | if (provider == "gdrive") { |
| 216 | authUrl.setUrl(GDRIVE_AUTH_URL); |
| 217 | params.addQueryItem("client_id", GDRIVE_CLIENT_ID); |
| 218 | params.addQueryItem("redirect_uri", m_redirectUri); |
| 219 | params.addQueryItem("response_type", "code"); |
nothing calls this directly
no outgoing calls
no test coverage detected