Skip to content

Commit

Permalink
[#38] use hashed-urls and therefore reimplements recall mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
rainu committed Mar 27, 2020
1 parent 9a61d39 commit f6f4639
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 94 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ For detailed explanation on how things work, check out [Nuxt.js docs](https://nu

## Changelog

### 0.9.21
* use hashed-urls - now you can share links to subpages without error [#38](https://github.com/rainu/dev-notes/issues/38)

### 0.9.19
* implements new note type: record [#5](https://github.com/rainu/dev-notes/issues/5)
* use a dedicated icon for draggable elements
Expand Down
43 changes: 33 additions & 10 deletions layouts/error.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
<template>
<v-app dark>
<h1 v-if="error.statusCode === 404">
{{ pageNotFound }}
</h1>
<h1 v-else>
{{ otherError }}
</h1>
<NuxtLink to="/">
Home page
</NuxtLink>
<v-app>
<template v-if="isRecallInProgress">
<v-container fill-height>
<v-row align="center"
justify="center">
<v-progress-circular
:size="250"
:width="10"
color="primary"
indeterminate
class="text-center"
>
{{$t('recall.progress')}}
</v-progress-circular>
</v-row>
</v-container>
</template>
<template v-else>
<h1 v-if="error.statusCode === 404">
{{ pageNotFound }}
</h1>
<h1 v-else>
{{ otherError }}
</h1>
<NuxtLink to="/">
Home page
</NuxtLink>
</template>
</v-app>
</template>

Expand All @@ -33,6 +51,11 @@ export default {
pageNotFound: '404 Not Found',
otherError: 'An error occurred'
}
},
computed: {
isRecallInProgress(){
return window.location.search && window.location.search.includes("recall")
}
}
}
</script>
Expand Down
3 changes: 3 additions & 0 deletions locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -494,5 +494,8 @@
"others":{
"title": "Andere"
}
},
"recall": {
"progress": "Einstellungen werden vorgenommen ..."
}
}
3 changes: 3 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -494,5 +494,8 @@
"others": {
"title": "Others"
}
},
"recall": {
"progress": "Settings will be applied ..."
}
}
42 changes: 3 additions & 39 deletions middleware/dropbox.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,5 @@
import { Dropbox } from "dropbox";
export default function ({ store }) {
//this middleware is only responsible for trigger refreshing the dropbox token

const refreshToken = (store) => {
let dpxAuth = store.getters['secrets/getDropboxAuth']
if(dpxAuth && dpxAuth.access_token) {
let dbx = new Dropbox({
fetch: fetch,
accessToken: dpxAuth.access_token,
clientId: process.env.dropbox.clientId,
})

dbx.usersGetCurrentAccount()
.then(user => store.commit('secrets/setDropboxUser', user))
.catch(() => store.dispatch('secrets/removeDropboxAuth'))
}
}

export default function ({ isHMR, app, store, route, params, error, redirect }) {
//dropbox use a oath2 auth workflow. that means the user will be redirected
//to the dropbox' login masked and after the login was successfully dropbox
//redirects the user back to our web-app

//this middleware is responsible for reading the dropbox auth token and store
//them into our store

let recall = route.query.recall && route.query.recall === 'dropbox' && route.hash
if(!recall) {
refreshToken(store)
return
}

let hashParams = new URLSearchParams(route.hash.substring(1))
let authParams = {}
for(let [key, value] of hashParams.entries()) {
authParams[key] = value
}

store.dispatch('secrets/setDropboxAuth', authParams)
.then(() => redirect(`/backup`))
.then(() => refreshToken(store))
store.dispatch('secrets/refreshDropboxToken')
}
14 changes: 14 additions & 0 deletions middleware/recall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function (ctx) {
//we need to handle requests which cannot handle fragments (url with #)
//so this middleware will look the real url and check if there is a recall query
//if so, redirect to own recall-page with all the origin data

if(window.location.search) {
let queryParams = new URLSearchParams(window.location.search.substr(1))

let recall = queryParams.has('recall')
if(recall) {
window.location = `${window.location.origin}${window.location.pathname}#/recall/${window.location.search}${window.location.hash}`
}
}
}
3 changes: 2 additions & 1 deletion nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const routerBase = process.env.DEPLOY_ENV === 'GH_PAGES' ? {
base: '/'
}
}
routerBase.router.middleware = ['encryption', 'dropbox']
routerBase.router.middleware = ['recall', 'encryption', 'dropbox']
routerBase.router.mode = 'hash'

export default {
...routerBase,
Expand Down
57 changes: 14 additions & 43 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "DevNotes",
"version": "0.9.20",
"version": "0.9.21",
"description": "A progressive web application (PWA) for notes.",
"author": "rainu",
"private": true,
Expand Down
3 changes: 3 additions & 0 deletions pages/backup/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
if (this.persistedPassword) {
this.password = this.persistedPassword
}
if(this.$route.query.selected) {
this.panel = parseInt(this.$route.query.selected)
}
}
}
</script>
Expand Down
65 changes: 65 additions & 0 deletions pages/recall.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<v-container fill-height>
<v-row align="center"
justify="center">
<v-progress-circular
:size="250"
:width="10"
color="primary"
indeterminate
class="text-center"
>
{{$t('recall.progress')}}
</v-progress-circular>
</v-row>
</v-container>
</template>

<script>
import { mapActions } from 'vuex';
export default {
computed: {
recall(){
return this.$route.query.recall
}
},
methods:{
...mapActions({
setDropboxAuth: 'secrets/setDropboxAuth',
refreshDropboxToken: 'secrets/refreshDropboxToken',
}),
handleDropbox(){
//dropbox use a oath2 auth workflow. that means the user will be redirected
//to the dropbox' login masked and after the login was successfully dropbox
//redirects the user back to our web-app
//this middleware is responsible for reading the dropbox auth token and store
//them into our store
let hashParams = new URLSearchParams(this.$route.hash.substring(2))
let authParams = {}
for(let [key, value] of hashParams.entries()) {
authParams[key] = value
}
this.setDropboxAuth(authParams)
.then(() => this.refreshDropboxToken())
.then(() => this.$router.replace(`/backup?selected=4`)) //the 4th panel is dropbox
}
},
mounted() {
switch (this.recall) {
case 'dropbox': this.handleDropbox(); return
default: {
console.error("Unknown recall!")
this.$router.replace('/') //goto home!
}
}
}
}
</script>

<style scoped>
</style>
Loading

0 comments on commit f6f4639

Please sign in to comment.