Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/entrypoints/options/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ async function init() {
}

updateButton('error');
showConnectionMessage('error', error.message);
const errorMessage = typeof error.message === 'string' ? error.message : JSON.stringify(error);
showConnectionMessage('error', errorMessage);
} finally {
isChecking = false;
cancelCurrentCheck = false;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/bookmarksync.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ async function validateBookmarkFiles(bookmarkFiles) {
const validator = await validate(BOOKMARK_SCHEMA_URI);

for (const bookmarkFile of bookmarkFiles) {
const validationResult = validator(bookmarkFile);
const validationResult = validator(bookmarkFile.data);
if (!validationResult.valid) {
const name = bookmarkFile.name || '<name not defined>';
throw new BookmarksDataNotValidError(`The bookmarks file with name '${name}' is not valid`);
Expand Down
46 changes: 44 additions & 2 deletions src/utils/github-bookmarks-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Octokit} from '@octokit/rest';
import {retry} from '@octokit/plugin-retry';
import optionsStorage from '@/utils/options-storage.js';
import {
AuthenticationError, DataNotFoundError, BookmarkSourceNotConfiguredError, RepositoryNotFoundError,
AuthenticationError, DataNotFoundError, BookmarkSourceNotConfiguredError, RepositoryNotFoundError, BookmarksDataNotValidError,
} from '@/utils/errors.js';

class GitHubBookmarksLoader {
Expand Down Expand Up @@ -30,6 +30,34 @@ class GitHubBookmarksLoader {
return bookmarkFiles;
}

extractFileName(url) {
// Github only gives url of files under a folder, so we need to extract file name from url
// example github url: https://api.github.com/repos/this-is-shivamsingh/bookmarks/contents/test_folder_3%2Fa.json
// Then full file name is after `contents` part
const fileName = url.split('contents').pop();
Copy link
Author

@this-is-shivamsingh this-is-shivamsingh Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Tested with multiple nested folders, and it successfully extracts file name


// Test_folder_3%2Fa.json -> needs get converted to test_folder_3/a.json
return decodeURIComponent(fileName.slice(1, fileName.length));
}

validateFile(file) {
const fileName = this.extractFileName(file.url);

if (!fileName.endsWith('.json') && !fileName.endsWith('.json')) {
throw new BookmarksDataNotValidError(`The bookmarks file with name ${fileName} contain invalid file extension for JSON file`);
}

if (typeof file.data !== 'string') {
throw new BookmarksDataNotValidError(`The bookmarks file with name '${fileName}' does not contain valid JSON`);
}

if (file.data.length === 0) {
throw new BookmarksDataNotValidError(`The bookmarks file with name '${fileName}' does not any content`);
}

return true;
}

async loadFromSource(sourceId, {force = false, cacheEtag = true} = {}) {
const options = await optionsStorage.getAll();
const repo = options[`${sourceId}_repo`];
Expand Down Expand Up @@ -99,7 +127,21 @@ class GitHubBookmarksLoader {
bookmarkFileResponses = [response];
}

const bookmarkFiles = bookmarkFileResponses.map(file => JSON.parse(file.data));
const bookmarkFiles = bookmarkFileResponses.map(file => {
const fileName = this.extractFileName(file.url);
// When user gives fileName, then that can be either of .txt, .png etc
// in those cases a validation is required to send a correct message
this.validateFile(file);

try {
return {
name: decodeURIComponent(fileName),
data: JSON.parse(file.data),
};
Comment on lines +137 to +140
Copy link
Author

@this-is-shivamsingh this-is-shivamsingh Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • In bookmarksync.js earlier we were only sending file data, and not the file name, therefore while showing error message it used to like this
The bookmarks file with name <name not defined> is not valid
  • This will be get fixed now for firefox, chrome and brave browser as well

} catch {
throw new BookmarksDataNotValidError(`The bookmarks file with name '${fileName}' does not contain valid JSON`);
}
});

if (cacheEtag) {
const etagPropertyName = `${sourceId}_etag`;
Expand Down