Allow the usage of a different instance for authentication.

This commit is contained in:
Kavin 2022-07-21 09:34:57 +05:30
parent 7803732da6
commit 37512b4e77
No known key found for this signature in database
GPG key ID: 49451E4482CC5BCD
13 changed files with 65 additions and 30 deletions

View file

@ -70,7 +70,7 @@ export default {
methods: { methods: {
async fetchSubscribedStatus() { async fetchSubscribedStatus() {
this.fetchJson( this.fetchJson(
this.apiUrl() + "/subscribed", this.authApiUrl() + "/subscribed",
{ {
channelId: this.channel.id, channelId: this.channel.id,
}, },
@ -113,7 +113,7 @@ export default {
} }
}, },
subscribeHandler() { subscribeHandler() {
this.fetchJson(this.apiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, { this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
channelId: this.channel.id, channelId: this.channel.id,

View file

@ -41,7 +41,7 @@ export default {
}, },
computed: { computed: {
getRssUrl(_this) { getRssUrl(_this) {
return _this.apiUrl() + "/feed/rss?authToken=" + _this.getAuthToken(); return _this.authApiUrl() + "/feed/rss?authToken=" + _this.getAuthToken();
}, },
}, },
mounted() { mounted() {
@ -66,7 +66,7 @@ export default {
}, },
methods: { methods: {
async fetchFeed() { async fetchFeed() {
return await this.fetchJson(this.apiUrl() + "/feed", { return await this.fetchJson(this.authApiUrl() + "/feed", {
authToken: this.getAuthToken(), authToken: this.getAuthToken(),
}); });
}, },

View file

@ -133,7 +133,7 @@ export default {
}, },
handleImport() { handleImport() {
this.fetchJson( this.fetchJson(
this.apiUrl() + "/import", this.authApiUrl() + "/import",
{ {
override: this.override, override: this.override,
}, },

View file

@ -49,7 +49,7 @@ export default {
}, },
methods: { methods: {
login() { login() {
this.fetchJson(this.apiUrl() + "/login", null, { this.fetchJson(this.authApiUrl() + "/login", null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
username: this.username, username: this.username,
@ -57,7 +57,7 @@ export default {
}), }),
}).then(resp => { }).then(resp => {
if (resp.token) { if (resp.token) {
this.setPreference("authToken" + this.hashCode(this.apiUrl()), resp.token); this.setPreference("authToken" + this.hashCode(this.authApiUrl()), resp.token);
window.location = "/"; // done to bypass cache window.location = "/"; // done to bypass cache
} else alert(resp.error); } else alert(resp.error);
}); });

View file

@ -56,7 +56,7 @@ export default {
}, },
mounted() { mounted() {
this.fetchPlaylists(); this.fetchPlaylists();
this.selectedPlaylist = this.getPreferenceString("selectedPlaylist" + this.hashCode(this.apiUrl())); this.selectedPlaylist = this.getPreferenceString("selectedPlaylist" + this.hashCode(this.authApiUrl()));
window.addEventListener("keydown", this.handleKeyDown); window.addEventListener("keydown", this.handleKeyDown);
window.blur(); window.blur();
}, },
@ -83,7 +83,7 @@ export default {
this.$refs.addButton.disabled = true; this.$refs.addButton.disabled = true;
this.processing = true; this.processing = true;
this.fetchJson(this.apiUrl() + "/user/playlists/add", null, { this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
playlistId: playlistId, playlistId: playlistId,
@ -94,13 +94,13 @@ export default {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}).then(json => { }).then(json => {
this.setPreference("selectedPlaylist" + this.hashCode(this.apiUrl()), playlistId); this.setPreference("selectedPlaylist" + this.hashCode(this.authApiUrl()), playlistId);
this.$emit("close"); this.$emit("close");
if (json.error) alert(json.error); if (json.error) alert(json.error);
}); });
}, },
async fetchPlaylists() { async fetchPlaylists() {
this.fetchJson(this.apiUrl() + "/user/playlists", null, { this.fetchJson(this.authApiUrl() + "/user/playlists", null, {
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),
}, },

View file

@ -57,14 +57,14 @@ export default {
}, },
computed: { computed: {
getRssUrl: _this => { getRssUrl: _this => {
return _this.apiUrl() + "/rss/playlists/" + _this.$route.query.list; return _this.authApiUrl() + "/rss/playlists/" + _this.$route.query.list;
}, },
}, },
mounted() { mounted() {
this.getPlaylistData(); this.getPlaylistData();
const playlistId = this.$route.query.list; const playlistId = this.$route.query.list;
if (this.authenticated && playlistId?.length == 36) if (this.authenticated && playlistId?.length == 36)
this.fetchJson(this.apiUrl() + "/user/playlists", null, { this.fetchJson(this.authApiUrl() + "/user/playlists", null, {
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),
}, },
@ -82,7 +82,7 @@ export default {
}, },
methods: { methods: {
async fetchPlaylist() { async fetchPlaylist() {
return await await this.fetchJson(this.apiUrl() + "/playlists/" + this.$route.query.list); return await await this.fetchJson(this.authApiUrl() + "/playlists/" + this.$route.query.list);
}, },
async getPlaylistData() { async getPlaylistData() {
this.fetchPlaylist() this.fetchPlaylist()
@ -96,7 +96,7 @@ export default {
if (this.loading || !this.playlist || !this.playlist.nextpage) return; if (this.loading || !this.playlist || !this.playlist.nextpage) return;
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - window.innerHeight) { if (window.innerHeight + window.scrollY >= document.body.offsetHeight - window.innerHeight) {
this.loading = true; this.loading = true;
this.fetchJson(this.apiUrl() + "/nextpage/playlists/" + this.$route.query.list, { this.fetchJson(this.authApiUrl() + "/nextpage/playlists/" + this.$route.query.list, {
nextpage: this.playlist.nextpage, nextpage: this.playlist.nextpage,
}).then(json => { }).then(json => {
this.playlist.relatedStreams.concat(json.relatedStreams); this.playlist.relatedStreams.concat(json.relatedStreams);

View file

@ -38,7 +38,7 @@ export default {
}, },
methods: { methods: {
fetchPlaylists() { fetchPlaylists() {
this.fetchJson(this.apiUrl() + "/user/playlists", null, { this.fetchJson(this.authApiUrl() + "/user/playlists", null, {
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),
}, },
@ -48,7 +48,7 @@ export default {
}, },
deletePlaylist(id) { deletePlaylist(id) {
if (confirm(this.$t("actions.delete_playlist_confirm"))) if (confirm(this.$t("actions.delete_playlist_confirm")))
this.fetchJson(this.apiUrl() + "/user/playlists/delete", null, { this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
playlistId: id, playlistId: id,
@ -65,7 +65,7 @@ export default {
createPlaylist() { createPlaylist() {
const name = prompt(this.$t("actions.create_playlist")); const name = prompt(this.$t("actions.create_playlist"));
if (name) if (name)
this.fetchJson(this.apiUrl() + "/user/playlists/create", null, { this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
name: name, name: name,

View file

@ -203,11 +203,33 @@
<label for="ddlInstanceSelection"><strong v-text="`${$t('actions.instance_selection')}:`" /></label> <label for="ddlInstanceSelection"><strong v-text="`${$t('actions.instance_selection')}:`" /></label>
<br /> <br />
<select id="ddlInstanceSelection" v-model="selectedInstance" class="select w-auto" @change="onChange($event)"> <select id="ddlInstanceSelection" v-model="selectedAuthInstance" class="select w-auto" @change="onChange($event)">
<option v-for="instance in instances" :key="instance.name" :value="instance.api_url" v-text="instance.name" /> <option v-for="instance in instances" :key="instance.name" :value="instance.api_url" v-text="instance.name" />
</select> </select>
<br /> <br />
<label for="chkAuthInstance"><strong v-text="`${$t('actions.different_auth_instance')}:`" /></label>
<br />
<input id="chkAuthInstance" v-model="authInstance" class="checkbox" type="checkbox" @change="onChange($event)" />
<template v-if="authInstance">
<br />
<label for="ddlAuthInstanceSelection"><strong v-text="`${$t('actions.instance_auth_selection')}:`" /></label>
<br />
<select
id="ddlAuthInstanceSelection"
v-model="selectedAuthInstance"
class="select w-auto"
@change="onChange($event)"
>
<option
v-for="instance in instances"
:key="instance.name"
:value="instance.api_url"
v-text="instance.name"
/>
</select>
</template>
<!-- options that are visible only when logged in --> <!-- options that are visible only when logged in -->
<br />
<div v-if="this.authenticated"> <div v-if="this.authenticated">
<label for="txtDeleteAccountPassword"><strong v-t="'actions.delete_account'" /></label> <label for="txtDeleteAccountPassword"><strong v-t="'actions.delete_account'" /></label>
<br /> <br />
@ -243,6 +265,8 @@ export default {
data() { data() {
return { return {
selectedInstance: null, selectedInstance: null,
authInstance: false,
selectedAuthInstance: null,
instances: [], instances: [],
sponsorBlock: true, sponsorBlock: true,
skipSponsor: true, skipSponsor: true,
@ -337,6 +361,8 @@ export default {
if (this.testLocalStorage) { if (this.testLocalStorage) {
this.selectedInstance = this.getPreferenceString("instance", "https://pipedapi.kavin.rocks"); this.selectedInstance = this.getPreferenceString("instance", "https://pipedapi.kavin.rocks");
this.authInstance = this.getPreferenceBoolean("authInstance", false);
this.selectedAuthInstance = this.getPreferenceString("auth_instance_url", this.selectedInstance);
this.sponsorBlock = this.getPreferenceBoolean("sponsorblock", true); this.sponsorBlock = this.getPreferenceBoolean("sponsorblock", true);
if (localStorage.getItem("selectedSkip") !== null) { if (localStorage.getItem("selectedSkip") !== null) {
@ -428,6 +454,8 @@ export default {
shouldReload = true; shouldReload = true;
localStorage.setItem("instance", this.selectedInstance); localStorage.setItem("instance", this.selectedInstance);
localStorage.setItem("authInstance", this.authInstance);
localStorage.setItem("auth_instance_url", this.selectedAuthInstance);
localStorage.setItem("sponsorblock", this.sponsorBlock); localStorage.setItem("sponsorblock", this.sponsorBlock);
var sponsorSelected = []; var sponsorSelected = [];
@ -466,7 +494,7 @@ export default {
return "https://www.ssllabs.com/ssltest/analyze.html?d=" + new URL(url).host + "&latest"; return "https://www.ssllabs.com/ssltest/analyze.html?d=" + new URL(url).host + "&latest";
}, },
async deleteAccount() { async deleteAccount() {
this.fetchJson(this.apiUrl() + "/user/delete", null, { this.fetchJson(this.authApiUrl() + "/user/delete", null, {
method: "POST", method: "POST",
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),
@ -482,12 +510,12 @@ export default {
}, },
logout() { logout() {
// reset the auth token // reset the auth token
localStorage.removeItem("authToken" + this.hashCode(this.apiUrl()), this.getAuthToken()); localStorage.removeItem("authToken" + this.hashCode(this.authApiUrl()));
// redirect to trending page // redirect to trending page
window.location = "/"; window.location = "/";
}, },
async invalidateSession() { async invalidateSession() {
this.fetchJson(this.apiUrl() + "/logout", null, { this.fetchJson(this.authApiUrl() + "/logout", null, {
method: "POST", method: "POST",
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),

View file

@ -49,7 +49,7 @@ export default {
}, },
methods: { methods: {
register() { register() {
this.fetchJson(this.apiUrl() + "/register", null, { this.fetchJson(this.authApiUrl() + "/register", null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
username: this.username, username: this.username,
@ -57,7 +57,7 @@ export default {
}), }),
}).then(resp => { }).then(resp => {
if (resp.token) { if (resp.token) {
this.setPreference("authToken" + this.hashCode(this.apiUrl()), resp.token); this.setPreference("authToken" + this.hashCode(this.authApiUrl()), resp.token);
window.location = "/"; // done to bypass cache window.location = "/"; // done to bypass cache
} else alert(resp.error); } else alert(resp.error);
}); });

View file

@ -39,7 +39,7 @@ export default {
}, },
mounted() { mounted() {
if (this.authenticated) if (this.authenticated)
this.fetchJson(this.apiUrl() + "/subscriptions", null, { this.fetchJson(this.authApiUrl() + "/subscriptions", null, {
headers: { headers: {
Authorization: this.getAuthToken(), Authorization: this.getAuthToken(),
}, },
@ -54,7 +54,7 @@ export default {
}, },
methods: { methods: {
handleButton(subscription) { handleButton(subscription) {
this.fetchJson(this.apiUrl() + (subscription.subscribed ? "/unsubscribe" : "/subscribe"), null, { this.fetchJson(this.authApiUrl() + (subscription.subscribed ? "/unsubscribe" : "/subscribe"), null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
channelId: subscription.url.split("/")[2], channelId: subscription.url.split("/")[2],

View file

@ -430,7 +430,7 @@ export default {
if (!this.channelId || !this.authenticated) return; if (!this.channelId || !this.authenticated) return;
this.fetchJson( this.fetchJson(
this.apiUrl() + "/subscribed", this.authApiUrl() + "/subscribed",
{ {
channelId: this.channelId, channelId: this.channelId,
}, },
@ -444,7 +444,7 @@ export default {
}); });
}, },
subscribeHandler() { subscribeHandler() {
this.fetchJson(this.apiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, { this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
channelId: this.channelId, channelId: this.channelId,

View file

@ -84,7 +84,9 @@
"delete_account": "Delete Account", "delete_account": "Delete Account",
"logout": "Logout from this device", "logout": "Logout from this device",
"minimize_recommendations_default": "Minimize Recommendations by default", "minimize_recommendations_default": "Minimize Recommendations by default",
"invalidate_session": "Logout all devices" "invalidate_session": "Logout all devices",
"different_auth_instance": "Use a different instance for authentication",
"instance_auth_selection": "Autentication Instance Selection"
}, },
"comment": { "comment": {
"pinned_by": "Pinned by", "pinned_by": "Pinned by",

View file

@ -154,8 +154,13 @@ const mixin = {
apiUrl() { apiUrl() {
return this.getPreferenceString("instance", "https://pipedapi.kavin.rocks"); return this.getPreferenceString("instance", "https://pipedapi.kavin.rocks");
}, },
authApiUrl() {
if (this.getPreferenceBoolean("authInstance", false)) {
return this.getPreferenceString("auth_instance_url", this.apiUrl());
} else return this.apiUrl();
},
getAuthToken() { getAuthToken() {
return this.getPreferenceString("authToken" + this.hashCode(this.apiUrl())); return this.getPreferenceString("authToken" + this.hashCode(this.authApiUrl()));
}, },
hashCode(s) { hashCode(s) {
return s.split("").reduce(function (a, b) { return s.split("").reduce(function (a, b) {