| 1200 | } |
| 1201 | |
| 1202 | void Backend::deleteOneDriveAppData(uint appId, const QString &token) |
| 1203 | { |
| 1204 | // Match Windows behavior: list all files under accountId/appId/, then delete each one |
| 1205 | // First, get the folder ID for CloudRedirect/<accountId>/<appId> |
| 1206 | QString folderPath = QString("CloudRedirect/%1/%2").arg(m_accountId).arg(appId); |
| 1207 | QUrl url(QString("https://graph.microsoft.com/v1.0/me/drive/root:/%1:?$select=id").arg(folderPath)); |
| 1208 | |
| 1209 | QNetworkRequest req(url); |
| 1210 | req.setRawHeader("Authorization", ("Bearer " + token).toUtf8()); |
| 1211 | |
| 1212 | auto *reply = m_nam->get(req); |
| 1213 | connect(reply, &QNetworkReply::finished, this, [this, reply, token, appId]() { |
| 1214 | reply->deleteLater(); |
| 1215 | int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); |
| 1216 | |
| 1217 | if (status == 404) { |
| 1218 | fprintf(stderr, "[Backend] OneDrive folder for app %u not found (nothing to delete)\n", appId); |
| 1219 | return; |
| 1220 | } |
| 1221 | if (reply->error() != QNetworkReply::NoError) { |
| 1222 | fprintf(stderr, "[Backend] Failed to get OneDrive folder for app %u: %s\n", |
| 1223 | appId, reply->errorString().toUtf8().constData()); |
| 1224 | return; |
| 1225 | } |
| 1226 | |
| 1227 | QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); |
| 1228 | QString folderId = doc.object().value("id").toString(); |
| 1229 | if (folderId.isEmpty()) { |
| 1230 | fprintf(stderr, "[Backend] OneDrive folder ID empty for app %u\n", appId); |
| 1231 | return; |
| 1232 | } |
| 1233 | |
| 1234 | // List all children recursively, delete files only (matches Windows behavior) |
| 1235 | listAndDeleteOneDriveFiles(folderId, token, appId); |
| 1236 | }); |
| 1237 | } |
| 1238 | |
| 1239 | void Backend::listAndDeleteOneDriveFiles(const QString &folderId, const QString &token, uint appId) |
| 1240 | { |
nothing calls this directly
no outgoing calls
no test coverage detected