Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use new JWT auth in all frontend API calls #743

Merged
merged 3 commits into from Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -44,7 +44,7 @@ serve:
## Runs server for local development
.PHONY: run-server
run-server:
GIN_MODE=$(GIN_MODE) SHIORI_DEVELOPMENT=$(SHIORI_DEVELOPMENT) SHIORI_DIR=$(SHIORI_DIR) go run main.go server
GIN_MODE=$(GIN_MODE) SHIORI_DEVELOPMENT=$(SHIORI_DEVELOPMENT) SHIORI_DIR=$(SHIORI_DIR) SHIORI_SECRET_KEY=shiori go run main.go server

## Generate swagger docs
.PHONY: swagger
Expand Down
193 changes: 99 additions & 94 deletions internal/view/assets/js/page/home.js
Expand Up @@ -214,7 +214,12 @@ export default {
var skipFetchTags = Error("skip fetching tags");

this.loading = true;
fetch(url, {headers: {'Content-Type': 'application/json'}})
fetch(url, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem("shiori-token"),
}
})
.then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -244,7 +249,7 @@ export default {

// Fetch tags if requested
if (fetchTags) {
return fetch(new URL("api/tags", document.baseURI), {headers: {'Content-Type': 'application/json'}});
return fetch(new URL("api/tags", document.baseURI), { headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") } });
} else {
this.loading = false;
throw skipFetchTags;
Expand Down Expand Up @@ -418,7 +423,7 @@ export default {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "post",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") }
}).then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -507,7 +512,7 @@ export default {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "put",
body: JSON.stringify(book),
headers: { "Content-Type": "application/json" }
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") }
}).then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -562,7 +567,7 @@ export default {
fetch(new URL("api/bookmarks", document.baseURI), {
method: "delete",
body: JSON.stringify(ids),
headers: { "Content-Type": "application/json" },
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") },
}).then(response => {
if (!response.ok) throw response;
return response;
Expand All @@ -588,61 +593,61 @@ export default {
}
});
},
ebookGenerate(items) {
// Check and filter items
if (typeof items !== "object") return;
if (!Array.isArray(items)) items = [items];

items = items.filter(item => {
var id = (typeof item.id === "number") ? item.id : 0,
index = (typeof item.index === "number") ? item.index : -1;

return id > 0 && index > -1;
});

if (items.length === 0) return;

// define variable and send request
var ids = items.map(item => item.id);
var data = {
ids: ids,
};
this.loading = true;
fetch(new URL("api/ebook", document.baseURI), {
method: "put",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
}).then(response => {
if (!response.ok) throw response;
return response.json();
}).then(json => {
this.selection = [];
this.editMode = false;
json.forEach(book => {
// download ebooks
const id = book.id;
if (book.hasEbook){
const ebook_url = new URL(`bookmark/${id}/ebook`, document.baseURI);
const downloadLink = document.createElement("a");
downloadLink.href = ebook_url.toString();
downloadLink.download = `${book.title}.epub`;
downloadLink.click();
}

var item = items.find(el => el.id === book.id);
ebookGenerate(items) {
// Check and filter items
if (typeof items !== "object") return;
if (!Array.isArray(items)) items = [items];

items = items.filter(item => {
var id = (typeof item.id === "number") ? item.id : 0,
index = (typeof item.index === "number") ? item.index : -1;

return id > 0 && index > -1;
});

if (items.length === 0) return;

// define variable and send request
var ids = items.map(item => item.id);
var data = {
ids: ids,
};
this.loading = true;
fetch(new URL("api/ebook", document.baseURI), {
method: "put",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") },
}).then(response => {
if (!response.ok) throw response;
return response.json();
}).then(json => {
this.selection = [];
this.editMode = false;
json.forEach(book => {
// download ebooks
const id = book.id;
if (book.hasEbook) {
const ebook_url = new URL(`bookmark/${id}/ebook`, document.baseURI);
const downloadLink = document.createElement("a");
downloadLink.href = ebook_url.toString();
downloadLink.download = `${book.title}.epub`;
downloadLink.click();
}

var item = items.find(el => el.id === book.id);
this.bookmarks.splice(item.index, 1, book);
});
}).catch(err => {
this.selection = [];
this.editMode = false;
this.getErrorMessage(err).then(msg => {
this.showErrorDialog(msg);
})
})
.finally(() => {
this.loading = false;
});
},
});
}).catch(err => {
this.selection = [];
this.editMode = false;
this.getErrorMessage(err).then(msg => {
this.showErrorDialog(msg);
})
})
.finally(() => {
this.loading = false;
});
},
showDialogUpdateCache(items) {
// Check and filter items
if (typeof items !== "object") return;
Expand Down Expand Up @@ -678,22 +683,22 @@ export default {
label: "Update Ebook as well",
type: "check",
value: this.appOptions.createEbook,
}],
}],
mainText: "Yes",
secondText: "No",
mainClick: (data) => {
var data = {
ids: ids,
createArchive: data.createArchive,
keepMetadata: data.keepMetadata,
createEbook: data.createEbook,
createEbook: data.createEbook,
};

this.dialog.loading = true;
fetch(new URL("api/cache", document.baseURI), {
method: "put",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") },
}).then(response => {
if (!response.ok) throw response;
return response.json();
Expand All @@ -702,36 +707,36 @@ export default {
this.editMode = false;
this.dialog.loading = false;
this.dialog.visible = false;
let faildedUpdateArchives = [];
let faildedCreateEbook = [];
json.forEach(book => {
var item = items.find(el => el.id === book.id);
this.bookmarks.splice(item.index, 1, book);

if (data.createArchive && !book.hasArchive){
faildedUpdateArchives.push(book.id);
console.error("can't update archive for bookmark id", book.id)
}
if (data.createEbook && !book.hasEbook){
faildedCreateEbook.push(book.id);
console.error("can't update ebook for bookmark id:", book.id)
}
});
if(faildedCreateEbook.length > 0 || faildedUpdateArchives.length > 0){
this.showDialog({
title: `Bookmarks Id that Update Action Faild`,
content: `Not all bookmarks could have their contents updated, but no files were overwritten.`,
mainText: "OK",
mainClick: () => {
this.dialog.visible = false;
},
})
}
}).catch(err => {
this.selection = [];
this.editMode = false;
this.dialog.loading = false;

let faildedUpdateArchives = [];
let faildedCreateEbook = [];
json.forEach(book => {
var item = items.find(el => el.id === book.id);
this.bookmarks.splice(item.index, 1, book);

if (data.createArchive && !book.hasArchive) {
faildedUpdateArchives.push(book.id);
console.error("can't update archive for bookmark id", book.id)
}
if (data.createEbook && !book.hasEbook) {
faildedCreateEbook.push(book.id);
console.error("can't update ebook for bookmark id:", book.id)
}
});
if (faildedCreateEbook.length > 0 || faildedUpdateArchives.length > 0) {
this.showDialog({
title: `Bookmarks Id that Update Action Faild`,
content: `Not all bookmarks could have their contents updated, but no files were overwritten.`,
mainText: "OK",
mainClick: () => {
this.dialog.visible = false;
},
})
}
}).catch(err => {
this.selection = [];
this.editMode = false;
this.dialog.loading = false;

this.getErrorMessage(err).then(msg => {
this.showErrorDialog(msg);
Expand Down Expand Up @@ -792,7 +797,7 @@ export default {
fetch(new URL("api/bookmarks/tags", document.baseURI), {
method: "put",
body: JSON.stringify(request),
headers: { "Content-Type": "application/json" },
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") },
}).then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -858,7 +863,7 @@ export default {
fetch(new URL("api/tag", document.baseURI), {
method: "PUT",
body: JSON.stringify(newData),
headers: { "Content-Type": "application/json" },
headers: { "Content-Type": "application/json", 'Authorization': 'Bearer ' + localStorage.getItem("shiori-token") },
}).then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down
10 changes: 9 additions & 1 deletion internal/view/assets/js/page/setting.js
Expand Up @@ -98,7 +98,12 @@ export default {
if (this.loading) return;

this.loading = true;
fetch(new URL("api/accounts", document.baseURI), {headers: {'Content-Type': 'application/json'}})
fetch(new URL("api/accounts", document.baseURI), {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem("shiori-token"),
}
})
.then(response => {
if (!response.ok) throw response;
return response.json();
Expand Down Expand Up @@ -168,6 +173,7 @@ export default {
body: JSON.stringify(request),
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + localStorage.getItem("shiori-token"),
}
}).then(response => {
if (!response.ok) throw response;
Expand Down Expand Up @@ -251,6 +257,7 @@ export default {
body: JSON.stringify(request),
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + localStorage.getItem("shiori-token"),
},
}).then(response => {
if (!response.ok) throw response;
Expand Down Expand Up @@ -280,6 +287,7 @@ export default {
body: JSON.stringify([account.username]),
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + localStorage.getItem("shiori-token")
},
}).then(response => {
if (!response.ok) throw response;
Expand Down
2 changes: 1 addition & 1 deletion internal/view/login.html
Expand Up @@ -123,7 +123,7 @@
document.cookie = `session-id=${json.message.session}; Path=${new URL(document.baseURI).pathname}; Expires=${json.message.expires}`;

// Save account data
localStorage.setItem("shiori-token", JSON.stringify(json.message.token));
localStorage.setItem("shiori-token", json.message.token);
localStorage.setItem("shiori-account", JSON.stringify(parseJWT(json.message.token).account));

// Go to destination page
Expand Down