Skip to content

Commit e588967

Browse files
authored
Fix Bug #3115: Add further driveId validation when processing API response data for a OneDrive Personal Shared Folder (#3116)
* Remove 'sea8cc6beffdb43d7976fbc7da445c639' check * Add further personal account driveId length checks when generating a /delta response for a Shared Folder * Fix selectRemoteTypeByRemoteDriveId() function to also use the remote item id so that the correct DB record is responded with. This ensures that 'localPathExtension =' reflects the correct local path extension and not some other incorrect local path * If the 'shared' JSON structure is missing, add a debug message * Add further checks for invalid 15 character driveId when creating Shared Folder references * Ensure that the 'driveId' value is correctly fetched and used due to 'UPPERCASE' and 'lowercase' values in API JSON response * Increase DB version to ensure all old records in the DB are purged * Sanitise JSON output for debug logging when enabled * Simplify isValidUTF8Timestamp() * Debug logging is not correct - missing all single --verbose entries which should be also included when performing a debug capture. * Based on application debug logs, if /delta fails to send Shared Folders, and the client goes to create these online, we know that these then exist online and are a Shared Folder. Handle in a similar manner to OneDrive Business Shared Folders logic to create the required database tie records if the API fails to send that data originally. * Remove double call to selectiveSync.isFileNameExcluded * Align invalid UTF-8 message to be consistent with other UTF-8 failure messages This PR specifically works around the Microsoft OneDrive change: * Microsoft moving all OneDrive Personal Accounts to a new backend platform. This is the 'sea8cc6beffdb43d7976fbc7da445c639' change: OneDrive/onedrive-api-docs#1890 * Microsoft failing to provide the Graph API data in the /delta call for accounts moved to the new backend platform: OneDrive/onedrive-api-docs#1891
1 parent 9051d0d commit e588967

File tree

5 files changed

+464
-165
lines changed

5 files changed

+464
-165
lines changed

src/itemdb.d

+6-5
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ Item makeDatabaseItem(JSONValue driveItem) {
225225

226226
final class ItemDatabase {
227227
// increment this for every change in the db schema
228-
immutable int itemDatabaseVersion = 15;
228+
immutable int itemDatabaseVersion = 16;
229229

230230
Database db;
231231
string insertItemStmt;
@@ -371,7 +371,7 @@ final class ItemDatabase {
371371
SELECT *
372372
FROM item
373373
WHERE type = 'remote'
374-
AND remoteDriveId = ?1
374+
AND remoteDriveId = ?1 AND remoteId = ?2
375375
";
376376
selectItemByParentIdStmt = "SELECT * FROM item WHERE driveId = ? AND parentId = ?";
377377
deleteItemByIdStmt = "DELETE FROM item WHERE driveId = ? AND id = ?";
@@ -633,13 +633,14 @@ final class ItemDatabase {
633633
}
634634
}
635635

636-
// This should return the 'remote' DB entry for the given 'remoteDriveId'
637-
bool selectRemoteTypeByRemoteDriveId(const(char)[] entryName, out Item item) {
636+
// This should return the 'remote' DB entry for the given 'remoteDriveId' and 'remoteId'
637+
bool selectRemoteTypeByRemoteDriveId(const(char)[] remoteDriveId, const(char)[] remoteId, out Item item) {
638638
synchronized(databaseLock) {
639639
auto p = db.prepare(selectRemoteTypeByRemoteDriveIdStmt);
640640
scope(exit) p.finalise(); // Ensure that the prepared statement is finalised after execution.
641641
try {
642-
p.bind(1, entryName);
642+
p.bind(1, remoteDriveId);
643+
p.bind(2, remoteId);
643644
auto r = p.exec();
644645
if (!r.empty) {
645646
item = buildItem(r);

src/main.d

+2-1
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,9 @@ int main(string[] cliArgs) {
151151
}
152152

153153
// Determine the application logging verbosity
154+
// - As these flags are used to reduce application processing when not required, specifically in a 'debug' scenario, both verboseLogging and debugLogging need to be enabled
154155
if (verbosityCount == 1) { verboseLogging = true;} // set __gshared bool verboseLogging in log.d
155-
if (verbosityCount >= 2) { debugLogging = true;} // set __gshared bool debugLogging in log.d
156+
if (verbosityCount >= 2) { verboseLogging = true; debugLogging = true;} // set __gshared bool verboseLogging & debugLogging in log.d
156157

157158
// Initialize the application logging class, as we know the application verbosity level
158159
// If we need to enable logging to a file, we can only do this once we know the application configuration which is done slightly later on

src/onedrive.d

+32-5
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,18 @@ class OneDriveApi {
572572
// After you have finished receiving all the changes, you may apply them to your local state. To check for changes in the future, call delta again with the @odata.deltaLink from the previous successful response.
573573
JSONValue getChangesByItemId(string driveId, string id, string deltaLink) {
574574
string[string] requestHeaders;
575-
// If Business Account add Prefer: Include-Feature=AddToOneDrive
576-
if ((appConfig.accountType != "personal") && ( appConfig.getValueBool("sync_business_shared_items"))) {
575+
576+
// From March 1st 2025, this needs to be added to ensure that Shared Folders are sent in the Delta Query Response
577+
if (appConfig.accountType == "personal") {
578+
// OneDrive Personal Account
577579
addIncludeFeatureRequestHeader(&requestHeaders);
580+
} else {
581+
// Business or SharePoint Library
582+
// Only add if configured to do so
583+
if (appConfig.getValueBool("sync_business_shared_items")) {
584+
// Feature enabled, add headers
585+
addIncludeFeatureRequestHeader(&requestHeaders);
586+
}
578587
}
579588

580589
string url;
@@ -586,15 +595,26 @@ class OneDriveApi {
586595
} else {
587596
url = deltaLink;
588597
}
598+
599+
// get the response
589600
return get(url, false, requestHeaders);
590601
}
591602

592603
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children
593604
JSONValue listChildren(string driveId, string id, string nextLink) {
594605
string[string] requestHeaders;
595-
// If Business Account add addIncludeFeatureRequestHeader() which should add Prefer: Include-Feature=AddToOneDrive
596-
if ((appConfig.accountType != "personal") && ( appConfig.getValueBool("sync_business_shared_items"))) {
606+
607+
// From March 1st 2025, this needs to be added to ensure that Shared Folders are sent in the Delta Query Response
608+
if (appConfig.accountType == "personal") {
609+
// OneDrive Personal Account
597610
addIncludeFeatureRequestHeader(&requestHeaders);
611+
} else {
612+
// Business or SharePoint Library
613+
// Only add if configured to do so
614+
if (appConfig.getValueBool("sync_business_shared_items")) {
615+
// Feature enabled, add headers
616+
addIncludeFeatureRequestHeader(&requestHeaders);
617+
}
598618
}
599619

600620
string url;
@@ -819,7 +839,14 @@ class OneDriveApi {
819839

820840
// Private OneDrive API Functions
821841
private void addIncludeFeatureRequestHeader(string[string]* headers) {
822-
if (debugLogging) {addLogEntry("Adding 'Include-Feature=AddToOneDrive' API request header as 'sync_business_shared_items' config option is enabled", ["debug"]);}
842+
if (appConfig.accountType == "personal") {
843+
// Add logging message for OneDrive Personal Accounts
844+
if (debugLogging) {addLogEntry("Adding 'Include-Feature=AddToOneDrive' API request header for OneDrive Personal Account Type", ["debug"]);}
845+
} else {
846+
// Add logging message for OneDrive Business Accounts
847+
if (debugLogging) {addLogEntry("Adding 'Include-Feature=AddToOneDrive' API request header as 'sync_business_shared_items' config option is enabled", ["debug"]);}
848+
}
849+
// Add feature to request headers
823850
(*headers)["Prefer"] = "Include-Feature=AddToOneDrive";
824851
}
825852

0 commit comments

Comments
 (0)