Skip to content
This repository was archived by the owner on Dec 16, 2024. It is now read-only.

Commit 9bdb1f5

Browse files
committed
fix: extension auth
1 parent 12f543b commit 9bdb1f5

File tree

7 files changed

+92
-49
lines changed

7 files changed

+92
-49
lines changed

src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ import ModalViewport from "@/components/modal/ModalViewport.vue";
8181
import ContextMenu from "@/components/overlay/ContextMenu.vue";
8282
import { log } from "./Logger";
8383
import Icon from "./components/utility/Icon.vue";
84-
import { WindowSelfMessage } from "./views/window.messages";
84+
import { WindowMessage } from "./views/window.messages";
8585
import { setupActor } from "@/ActorLogic";
8686
8787
const store = useStore();
@@ -110,7 +110,7 @@ provideApolloClient(apolloClient);
110110
// Set up the actor user
111111
window.addEventListener("message", (e) => {
112112
if (e.origin === location.origin) {
113-
const data = e.data as WindowSelfMessage;
113+
const data = e.data as WindowMessage;
114114
115115
log.info("Received message from popup", `${JSON.stringify(data)}`);
116116

src/components/utility/LoginButton.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<button
3-
v-if="actor.user === null"
3+
v-if="actor.user === null || redirect"
44
class="twitch-button"
55
:platform="platform"
66
@click="() => oauth2Authorize()"
@@ -32,11 +32,17 @@ const actor = useActor();
3232
const { t } = useI18n();
3333
const auth = useAuth();
3434
35+
const props = defineProps<{ redirect?: boolean }>();
36+
3537
const platform = ref<User.UserConnectionPlatform>("TWITCH");
3638
3739
/** Request the user to authorize with a third party platform */
3840
const oauth2Authorize = () => {
39-
auth.prompt(platform.value, false);
41+
if (props.redirect) {
42+
auth.redirect(platform.value, false);
43+
} else {
44+
auth.prompt(platform.value, false);
45+
}
4046
};
4147
4248
const { open } = useContextMenu();

src/composables/useAuth.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,25 @@ export function useAuth() {
4343
);
4444
}
4545

46+
function redirect(provider: User.Connection.Platform, isLink: boolean) {
47+
const store = useStore();
48+
49+
const route =
50+
`auth?platform=${provider.toLowerCase()}` +
51+
(store.authToken ? `&token=${store.authToken}` : "") +
52+
(isLink ? "&link_connection=true" : "");
53+
54+
window.location.assign(`${import.meta.env.VITE_APP_API_REST}/${route}`);
55+
}
56+
4657
function logout(): Promise<void> {
4758
const store = useStore();
4859
return popup("auth/logout" + (store.authToken ? `?token=${store.authToken}` : ""));
4960
}
5061

5162
return {
5263
prompt,
64+
redirect,
5365
logout,
5466
};
5567
}

src/store/main.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,13 @@ export const useStore = defineStore("main", {
113113
},
114114
});
115115

116+
setInterval(() => {
117+
const token = localStorage.getItem(LocalStorageKeys.AUTH_TOKEN);
118+
const store = useStore();
119+
if (token !== store.authToken) {
120+
store.setAuthToken(token);
121+
}
122+
}, 1000);
123+
116124
export type Theme = "light" | "dark";
117125
export type NotFoundMode = "troll-despair" | "pot-friend";

src/views/ExtensionAuth.vue

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
11
<template>
22
<div class="extension-auth-content">
3-
<LoginButton v-if="!actor.user" />
3+
<LoginButton redirect />
44
</div>
55
</template>
66

77
<script setup lang="ts">
8-
import { watch } from "vue";
9-
import { useActor } from "@/store/actor";
10-
import { useStore } from "@/store/main";
11-
import LoginButton from "@/components/utility/LoginButton.vue";
8+
import { useRouter } from "vue-router";
9+
import LoginButton from "../components/utility/LoginButton.vue";
10+
import { useStore } from "../store/main";
1211
12+
const router = useRouter();
1313
const store = useStore();
14-
const actor = useActor();
15-
window.addEventListener("message", function listener(e) {
16-
if (e.origin !== "https://www.twitch.tv") return;
17-
if (e.data !== "7tv-token-request") return;
14+
const opener = window.opener as Window;
1815
19-
window.removeEventListener("message", listener);
20-
watch(
21-
() => store.authToken,
22-
(t) => {
23-
if (!t) return;
24-
e.source?.postMessage({ type: "7tv-token", token: t }, { targetOrigin: "https://www.twitch.tv/*" });
25-
},
26-
{ immediate: true },
27-
);
28-
});
16+
function main() {
17+
if (!opener) {
18+
router.push("/");
19+
} else if (store.authToken) {
20+
opener.postMessage({ type: "7tv-token", token: store.authToken }, "https://www.twitch.tv");
21+
window.close();
22+
} else {
23+
window.sessionStorage.setItem("7tv-extension-auth", "true");
24+
}
25+
}
26+
27+
main();
2928
</script>
3029

3130
<style lang="scss">

src/views/OAuth2.vue

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<script setup lang="ts">
66
import { useRoute, useRouter } from "vue-router";
77
import { useHead } from "@vueuse/head";
8-
import { publishSelfMessage } from "./window.messages";
8+
import { publishMessage } from "./window.messages";
9+
import { useStore } from "../store/main";
910
1011
useHead({
1112
title: "7TV | Authentication (OAuth2 Callback)",
@@ -16,42 +17,59 @@ useHead({
1617
1718
const route = useRoute();
1819
const router = useRouter();
20+
const opener = window.opener as Window;
1921
2022
function handleRoute() {
21-
if (!window.opener) {
23+
if (!opener) {
2224
router.replace("/");
2325
return;
2426
}
2527
26-
// Parse the token as a URLSearchParams
2728
const params = new URLSearchParams(route.hash.slice(1));
2829
const token = params.get("token");
29-
const wasLinked = params.get("linked") === "true";
30-
const isLogout = params.get("logout") === "true";
3130
32-
if (isLogout) {
33-
publishSelfMessage({ event: "LOGOUT_SUCCESS" });
34-
window.close();
35-
return;
31+
let is7TV;
32+
try {
33+
is7TV = opener.location.origin === window.origin;
34+
} catch (e) {
35+
is7TV = false;
3636
}
3737
38-
if (wasLinked) {
39-
publishSelfMessage({ event: "LOGIN_LINKED" });
40-
window.close();
41-
return;
42-
}
38+
if (is7TV) {
39+
const wasLinked = params.get("linked") === "true";
40+
const isLogout = params.get("logout") === "true";
4341
44-
if (!token) {
45-
publishSelfMessage({ event: "LOGIN_FAILED" });
46-
window.close();
47-
return;
42+
// Parse the token as a URLSearchParams
43+
44+
if (isLogout) {
45+
publishMessage({ event: "LOGOUT_SUCCESS" });
46+
window.close();
47+
return;
48+
}
49+
50+
if (wasLinked) {
51+
publishMessage({ event: "LOGIN_LINKED" });
52+
window.close();
53+
return;
54+
}
55+
56+
if (!token) {
57+
publishMessage({ event: "LOGIN_FAILED" });
58+
window.close();
59+
return;
60+
}
61+
62+
// Send the token back to the parent window
63+
publishMessage({
64+
event: "LOGIN_TOKEN",
65+
token,
66+
});
67+
} else if (token && window.sessionStorage.getItem("7tv-extension-auth") === "true") {
68+
const store = useStore();
69+
store.setAuthToken(token);
70+
opener.postMessage({ type: "7tv-token", token }, "https://www.twitch.tv");
4871
}
4972
50-
// Send the token back to the parent window
51-
publishSelfMessage({
52-
event: "LOGIN_TOKEN",
53-
token,
54-
});
5573
window.close();
5674
}
5775

src/views/window.messages.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
export type WindowSelfMessage =
1+
export type WindowMessage =
22
| { event: "LOGIN_TOKEN"; token: string }
33
| { event: "LOGIN_FAILED" }
44
| { event: "LOGIN_LINKED" }
55
| { event: "LOGOUT_SUCCESS" };
66

7-
export function publishSelfMessage(event: WindowSelfMessage) {
7+
export function publishMessage(event: WindowMessage, origin = window.origin) {
88
if (!window.opener) throw new Error("No window.opener");
99

10-
window.opener.postMessage(event, window.origin);
10+
window.opener.postMessage(event, origin);
1111
}

0 commit comments

Comments
 (0)