Skip to content

Commit

Permalink
Add bookmarklet
Browse files Browse the repository at this point in the history
  • Loading branch information
RadhiFadlillah committed Jun 6, 2018
1 parent b1ae14e commit 4b93937
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 25 deletions.
36 changes: 22 additions & 14 deletions cmd/serve/assets-prod.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cmd/serve/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func NewServeCmd(db dt.Database, dataDir string) *cobra.Command {
router.GET("/login", hdl.serveLoginPage)
router.GET("/bookmark/:id", hdl.serveBookmarkCache)
router.GET("/thumb/:id", hdl.serveThumbnailImage)
router.GET("/submit", hdl.serveSubmitPage)

router.POST("/api/login", hdl.apiLogin)
router.GET("/api/bookmarks", hdl.apiGetBookmarks)
Expand Down
14 changes: 13 additions & 1 deletion cmd/serve/web-handler-api.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ func (h *webHandler) apiGetTags(w http.ResponseWriter, r *http.Request, ps httpr

// apiInsertBookmark is handler for POST /api/bookmark
func (h *webHandler) apiInsertBookmark(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Enable CORS for this endpoint
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

// Check token
err := h.checkAPIToken(r)
checkError(err)
Expand Down Expand Up @@ -157,7 +162,14 @@ func (h *webHandler) apiInsertBookmark(w http.ResponseWriter, r *http.Request, p

// Save bookmark to database
_, err = h.db.InsertBookmark(book)
checkError(err)
if err != nil {
fmt.Println(err)
book.ID = h.db.GetBookmarkID(book.URL)
book.Modified = time.Now().UTC().Format("2006-01-02 15:04:05")
fmt.Println(book.ID, book.Modified)
_, err = h.db.UpdateBookmarks(book)
checkError(err)
}

// Return new saved result
err = json.NewEncoder(w).Encode(&book)
Expand Down
6 changes: 6 additions & 0 deletions cmd/serve/web-handler-ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ func (h *webHandler) serveIndexPage(w http.ResponseWriter, r *http.Request, ps h
checkError(err)
}

// serveSubmitPage is handler for GET /submit
func (h *webHandler) serveSubmitPage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
err := serveFile(w, "submit.html")
checkError(err)
}

// serveLoginPage is handler for GET /login
func (h *webHandler) serveLoginPage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Check token
Expand Down
21 changes: 16 additions & 5 deletions cmd/serve/web-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,39 @@ func newWebHandler(db dt.Database, dataDir string) (*webHandler, error) {
func (h *webHandler) checkToken(r *http.Request) error {
tokenCookie, err := r.Cookie("token")
if err != nil {
return fmt.Errorf("Token does not exist")
return fmt.Errorf("Token error: Token does not exist")
}

token, err := jwt.Parse(tokenCookie.Value, h.jwtKeyFunc)
if err != nil {
return err
return fmt.Errorf("Token error: %v", err)
}

claims := token.Claims.(jwt.MapClaims)
return claims.Valid()
err = claims.Valid()
if err != nil {
return fmt.Errorf("Token error: %v", err)
}

return nil
}

func (h *webHandler) checkAPIToken(r *http.Request) error {
token, err := request.ParseFromRequest(r,
request.AuthorizationHeaderExtractor,
h.jwtKeyFunc)
if err != nil {
return err
// Try to check in cookie
return h.checkToken(r)
}

claims := token.Claims.(jwt.MapClaims)
return claims.Valid()
err = claims.Valid()
if err != nil {
return fmt.Errorf("Token error: %v", err)
}

return nil
}

func (h *webHandler) jwtKeyFunc(token *jwt.Token) (interface{}, error) {
Expand Down
3 changes: 3 additions & 0 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type Database interface {

// DeleteAccounts removes all record with matching usernames
DeleteAccounts(usernames ...string) error

// GetBookmarkID fetchs bookmark ID based by its url
GetBookmarkID(url string) int
}

func checkError(err error) {
Expand Down
9 changes: 8 additions & 1 deletion database/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func (db *SQLiteDatabase) SearchBookmarks(orderLatest bool, keyword string, tags

// Set order clause
if orderLatest {
query += ` ORDER BY id DESC`
query += ` ORDER BY modified DESC`
}

// Fetch bookmarks
Expand Down Expand Up @@ -552,3 +552,10 @@ func (db *SQLiteDatabase) GetNewID(table string) (int, error) {

return tableID, nil
}

// GetBookmarkID fetchs bookmark ID based by its url
func (db *SQLiteDatabase) GetBookmarkID(url string) int {
var bookmarkID int
db.Get(&bookmarkID, `SELECT id FROM bookmark WHERE url = ?`, url)
return bookmarkID
}
2 changes: 1 addition & 1 deletion view/css/stylesheet.css

Large diffs are not rendered by default.

43 changes: 41 additions & 2 deletions view/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
</a>
</yla-tooltip>
<yla-tooltip placement="right" content="Add new bookmark">
<a @click="showDialogAdd" v-show="!editMode && !loading">
<a :href="bookmarklet" @click="showDialogAdd" v-show="!editMode && !loading">
<span>+Shiori</span>
<i class="fas fa-plus fa-fw"></i>
</a>
</yla-tooltip>
Expand Down Expand Up @@ -197,6 +198,7 @@
nightMode: false,
editMode: false,
selected: [],
bookmarklet: '',
dialogTags: {
visible: false,
loading: false,
Expand Down Expand Up @@ -318,7 +320,8 @@
this.dialogTags.visible = false;
this.loadData();
},
showDialogAdd() {
showDialogAdd(e) {
e.preventDefault();
this.showDialog({
title: 'New Bookmark',
content: 'Create a new bookmark',
Expand Down Expand Up @@ -643,6 +646,42 @@
this.listView = listView === '1';
this.nightMode = nightMode === '1';

// Create bookmarklet
var shioriURL = location.href.replace(/\/+$/g, ''),
baseBookmarklet = `(function () {
var shioriURL = '$SHIORI_URL',
bookmarkURL = location.href,
submitURL = shioriURL + '/submit?url=' + encodeURIComponent(bookmarkURL);
if (bookmarkURL.startsWith('https://') && !shioriURL.startsWith('https://')) {
window.open(submitURL, '_blank');
return;
}
var i = document.createElement('iframe');
i.src = submitURL;
i.frameBorder = '0';
i.allowTransparency = true;
i.style.position = 'fixed';
i.style.top = 0;
i.style.left = 0;
i.style.width = '100%';
i.style.height = '100%';
i.style.zIndex = 99999;
document.body.appendChild(i);
window.addEventListener('message', function onMessage(e) {
if (e.origin !== shioriURL) return;
if (e.data !== 'finished') return;
window.removeEventListener('message', onMessage);
document.body.removeChild(i);
});
}())`;

this.bookmarklet = 'javascript:' + baseBookmarklet
.replace('$SHIORI_URL', shioriURL)
.replace(/\s+/gm, ' ');

// Load data
this.loadData();
}
Expand Down
22 changes: 22 additions & 0 deletions view/less/stylesheet.less
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ body {
display: block;
color: var(--colorSidebar);
flex-shrink: 0;
>span {
display: block;
height: 0;
line-height: 0;
overflow: hidden;
}
&:hover,
&:focus {
background-color: #232323;
Expand Down Expand Up @@ -680,6 +686,22 @@ body {
}
}

#submit-page {
background-color: transparent;
.yla-dialog__header {
text-align: center;
}
&:not(.iframe) {
background-color: var(--bg);
.yla-dialog__overlay {
background-color: transparent;
.yla-dialog {
border: 1px solid var(--border);
}
}
}
}

.yla-tooltip {
@media (max-width: 800px) {
display: none;
Expand Down
12 changes: 11 additions & 1 deletion view/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,22 @@
timeout: 10000
})
.then(function (response) {
// Save token
var token = response.data;
Cookies.set('token', token, {
expires: this.rememberMe ? 7 : 1
});

location.href = '/';
// Set destination URL
var rx = /[&?]dst=([^&]+)(&|$)/g,
match = rx.exec(location.href);

if (match == null) {
location.href = '/';
} else {
var dst = match[1];
location.href = decodeURIComponent(dst);
}
})
.catch(function (error) {
var errorMsg = (error.response ? error.response.data : error.message).trim();
Expand Down
Loading

0 comments on commit 4b93937

Please sign in to comment.