Fetch microsub endpoint from user (and use it)
This commit is contained in:
parent
142b6ef28b
commit
dcd79702db
|
|
@ -8,6 +8,7 @@
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"micropub-helper": "^1.4.0",
|
"micropub-helper": "^1.4.0",
|
||||||
"node-sass": "^4.9.3",
|
"node-sass": "^4.9.3",
|
||||||
"vue": "^2.5.17",
|
"vue": "^2.5.17",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Micropub from 'micropub-helper';
|
import Micropub from 'micropub-helper';
|
||||||
import helper from '@/helpers';
|
import helper from '@/helpers';
|
||||||
|
import relScraper from '@/helpers/rel-scraper'
|
||||||
|
|
||||||
const CLIENT_ID = 'https://p83.nl/'
|
const CLIENT_ID = 'https://p83.nl/'
|
||||||
|
|
||||||
|
|
@ -61,14 +62,14 @@
|
||||||
state: state,
|
state: state,
|
||||||
scope: 'create post channels timeline'
|
scope: 'create post channels timeline'
|
||||||
})
|
})
|
||||||
|
|
||||||
micropub.getAuthUrl().then(url => {
|
micropub.getAuthUrl().then(url => {
|
||||||
let options = {
|
let options = {
|
||||||
micropubEndpoint: micropub.options.micropubEndpoint,
|
|
||||||
tokenEndpoint: micropub.options.tokenEndpoint,
|
|
||||||
loginState: state
|
loginState: state
|
||||||
}
|
}
|
||||||
this.$store.dispatch('saveEndpoints', options)
|
this.$store.dispatch('saveEndpoints', options).then(() => {
|
||||||
window.location = url
|
window.location = url
|
||||||
|
})
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}).catch(err => console.log(err))
|
}).catch(err => console.log(err))
|
||||||
}
|
}
|
||||||
|
|
@ -92,22 +93,36 @@
|
||||||
me: this.$route.query['me'],
|
me: this.$route.query['me'],
|
||||||
state: this.$store.state.loginState,
|
state: this.$store.state.loginState,
|
||||||
scope: 'create post channels timeline',
|
scope: 'create post channels timeline',
|
||||||
tokenEndpoint: this.$store.state.tokenEndpoint
|
|
||||||
})
|
})
|
||||||
|
|
||||||
micropub
|
relScraper(this.$route.query['me']).then(rels => {
|
||||||
.getToken(code)
|
micropub.options.tokenEndpoint = rels.token_endpoint
|
||||||
.then(token => {
|
micropub.options.authEndpoint = rels.auth_endpoint
|
||||||
this.$store.dispatch('tokenResponse', {
|
micropub.options.micropubEndpoint = rels.micropub
|
||||||
access_token: token,
|
|
||||||
me: micropub.options.me,
|
let options = {
|
||||||
scope: micropub.options.scope
|
tokenEndpoint: rels.token_endpoint,
|
||||||
|
authEndpoint: rels.auth_endpoint,
|
||||||
|
micropubEndpoint: rels.micropub,
|
||||||
|
microsubEndpoint: rels.microsub
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$store.dispatch('saveEndpoints', options)
|
||||||
|
|
||||||
|
micropub
|
||||||
|
.getToken(code)
|
||||||
|
.then(token => {
|
||||||
|
this.$store.dispatch('tokenResponse', {
|
||||||
|
access_token: token,
|
||||||
|
me: micropub.options.me,
|
||||||
|
scope: micropub.options.scope
|
||||||
|
})
|
||||||
|
this.show = false
|
||||||
|
this.$router.push('/')
|
||||||
})
|
})
|
||||||
this.show = false
|
// eslint-disable-next-line
|
||||||
this.$router.push('/')
|
.catch(err => console.log(err));
|
||||||
})
|
})
|
||||||
// eslint-disable-next-line
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
103
src/helpers/rel-scraper.js
Normal file
103
src/helpers/rel-scraper.js
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
import fetch from 'isomorphic-fetch'
|
||||||
|
|
||||||
|
export default function(url) {
|
||||||
|
let baseUrl = url;
|
||||||
|
let endpoints = {
|
||||||
|
micropub: null,
|
||||||
|
microsub: null,
|
||||||
|
authorization_endpoint: null,
|
||||||
|
token_endpoint: null,
|
||||||
|
media_endpoint: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fetch(url)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
return reject('Error getting page');
|
||||||
|
}
|
||||||
|
baseUrl = res.url;
|
||||||
|
|
||||||
|
// Check for endpoints in headers
|
||||||
|
const linkHeaders = res.headers.get('link');
|
||||||
|
if (linkHeaders) {
|
||||||
|
const links = linkHeaders.split(',');
|
||||||
|
links.forEach(link => {
|
||||||
|
Object.keys(endpoints).forEach(key => {
|
||||||
|
const rel = link.match(/rel=("([^"]*)"|([^,"<]+))/);
|
||||||
|
if (
|
||||||
|
rel &&
|
||||||
|
rel[1] &&
|
||||||
|
(' ' + rel[1].toLowerCase() + ' ').indexOf(' ' + key + ' ') >= 0
|
||||||
|
) {
|
||||||
|
const linkValues = link.match(/[^<>|\s]+/g);
|
||||||
|
if (linkValues && linkValues[0]) {
|
||||||
|
let endpointUrl = linkValues[0];
|
||||||
|
endpointUrl = new URL(endpointUrl, url).toString();
|
||||||
|
endpoints[key] = endpointUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then(html => {
|
||||||
|
// Get rel links
|
||||||
|
const rels = htmlScraper(html, baseUrl);
|
||||||
|
|
||||||
|
// Save necessary endpoints.
|
||||||
|
if (rels) {
|
||||||
|
Object.keys(endpoints).forEach(key => {
|
||||||
|
if (rels[key] && rels[key][0]) {
|
||||||
|
endpoints[key] = rels[key][0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resolve(endpoints);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log(err);
|
||||||
|
reject('Error fetching url');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function htmlScraper(htmlString, url) {
|
||||||
|
let rels = {};
|
||||||
|
let baseUrl = url;
|
||||||
|
|
||||||
|
const doc = new DOMParser().parseFromString(htmlString, 'text/html');
|
||||||
|
const baseEl = doc.querySelector('base[href]');
|
||||||
|
const relEls = doc.querySelectorAll('[rel][href]');
|
||||||
|
|
||||||
|
if (baseEl) {
|
||||||
|
const value = baseEl.getAttribute('href');
|
||||||
|
const url = new URL(value, url);
|
||||||
|
baseUrl = url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relEls.length) {
|
||||||
|
relEls.forEach(relEl => {
|
||||||
|
const names = relEl
|
||||||
|
.getAttribute('rel')
|
||||||
|
.toLowerCase()
|
||||||
|
.split('\\s+');
|
||||||
|
const value = relEl.getAttribute('href');
|
||||||
|
if (names.length && value !== null) {
|
||||||
|
names.forEach(name => {
|
||||||
|
if (!rels[name]) {
|
||||||
|
rels[name] = [];
|
||||||
|
}
|
||||||
|
const url = new URL(value, baseUrl).toString();
|
||||||
|
if (rels[name].indexOf(url) === -1) {
|
||||||
|
rels[name].push(url)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return rels
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,6 @@ import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import Micropub from 'micropub-helper';
|
import Micropub from 'micropub-helper';
|
||||||
|
|
||||||
const baseurl = "https://microsub.stuifzandapp.com/microsub"
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
|
|
@ -54,7 +52,7 @@ export default new Vuex.Store({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
fetchChannels({commit}) {
|
fetchChannels({commit}) {
|
||||||
fetch(baseurl + '?action=channels', {
|
fetch(this.state.microsubEndpoint + '?action=channels', {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Bearer ' + this.state.access_token
|
'Authorization': 'Bearer ' + this.state.access_token
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +66,7 @@ export default new Vuex.Store({
|
||||||
commit('clearTimeline', {channel: channel})
|
commit('clearTimeline', {channel: channel})
|
||||||
},
|
},
|
||||||
fetchTimeline({commit}, channel) {
|
fetchTimeline({commit}, channel) {
|
||||||
let url = baseurl + '?action=timeline&channel=' + channel.uid
|
let url = this.state.microsubEndpoint + '?action=timeline&channel=' + channel.uid
|
||||||
if (channel.after) {
|
if (channel.after) {
|
||||||
url += '&after=' + channel.after;
|
url += '&after=' + channel.after;
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +97,7 @@ export default new Vuex.Store({
|
||||||
commit('newAccessToken', response)
|
commit('newAccessToken', response)
|
||||||
},
|
},
|
||||||
markRead(x, {channel, entry}) {
|
markRead(x, {channel, entry}) {
|
||||||
let url = baseurl + '?action=timeline&method=mark_read&channel=' + encodeURIComponent(channel) + '&entry=' + encodeURIComponent(entry);
|
let url = this.state.microsubEndpoint + '?action=timeline&method=mark_read&channel=' + encodeURIComponent(channel) + '&entry=' + encodeURIComponent(entry);
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user