adn login implementation and search not disappearing fix
This commit is contained in:
parent
f19189f1dc
commit
a4d3f8a34e
0
components/ADN/GetAnime.ts
Normal file
0
components/ADN/GetAnime.ts
Normal file
0
components/ADN/ListEpisodes.ts
Normal file
0
components/ADN/ListEpisodes.ts
Normal file
@ -19,7 +19,7 @@
|
||||
<option value="adn">ADN</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll' || !isLoggedInCR && service === 'adn'" class="relative flex flex-col">
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||
<input
|
||||
v-model="search"
|
||||
@input="handleInputChange"
|
||||
@ -33,7 +33,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="searchActive"
|
||||
class="absolute top-full left-0 h-60 w-full bg-[#868585] rounded-xl overflow-y-scroll grid grid-cols-2 gap-3 p-2 z-10"
|
||||
class="absolute top-full left-0 h-40 w-full bg-[#868585] rounded-xl overflow-y-scroll grid grid-cols-2 gap-3 p-2 z-10"
|
||||
style="-webkit-app-region: no-drag"
|
||||
>
|
||||
<button v-for="result in crunchySearchResults" @click="selectShow(result)" class="flex flex-row gap-3 px-3 py-3 hover:bg-[#747474] rounded-xl">
|
||||
@ -61,10 +61,10 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll'" class="relative flex flex-col">
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||
<input v-model="url" type="text" name="text" placeholder="URL" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||
</div>
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll'" class="relative flex flex-col">
|
||||
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||
<input
|
||||
@click="getFolderPath()"
|
||||
v-model="path"
|
||||
@ -80,6 +80,11 @@
|
||||
class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer"
|
||||
>Click to Login</button>
|
||||
</div>
|
||||
<div v-if="!isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||
<button @click="openADNLogin"
|
||||
class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer"
|
||||
>Click to Login</button>
|
||||
</div>
|
||||
<div class="relative flex flex-col mt-auto">
|
||||
<button @click="switchToSeason" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center">
|
||||
<div class="flex flex-row items-center justify-center transition-all" :class="isFetchingSeasons ? 'opacity-0' : 'opacity-100'">
|
||||
@ -91,7 +96,6 @@
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<!-- {{ searchresults }} -->
|
||||
</div>
|
||||
<div v-if="tab === 2" class="flex flex-col mt-5 gap-3.5 h-full" style="-webkit-app-region: no-drag">
|
||||
<div class="relative flex flex-col">
|
||||
@ -282,7 +286,7 @@ const searchActive = ref<boolean>(false)
|
||||
const crunchySearchResults = ref<CrunchyrollSearchResults>()
|
||||
const adnSearchResults = ref<ADNSearchResults>()
|
||||
const CRselectedShow = ref<CrunchyrollSearchResult | null>()
|
||||
const ADNselectedShow = ref<ADNSearchResult>()
|
||||
const ADNselectedShow = ref<ADNSearchResult | null>()
|
||||
const url = ref<string>('')
|
||||
const path = ref<string>()
|
||||
const service = ref<'adn' | 'crunchyroll'>('crunchyroll')
|
||||
@ -302,7 +306,9 @@ const isFetchingEpisodes = ref<number>(0)
|
||||
const isFetchingResults = ref<number>(0)
|
||||
|
||||
const isLoggedInCR = ref<boolean>(false)
|
||||
let interval: NodeJS.Timeout;
|
||||
const isLoggedInADN = ref<boolean>(false)
|
||||
let intervalcr: NodeJS.Timeout;
|
||||
let intervaladn: NodeJS.Timeout;
|
||||
|
||||
const checkIfLoggedInCR = async () => {
|
||||
const { data, error } = await checkAccount('CR')
|
||||
@ -312,8 +318,8 @@ const checkIfLoggedInCR = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
if (intervalcr) {
|
||||
clearInterval(intervalcr)
|
||||
}
|
||||
|
||||
isLoggedInCR.value = true
|
||||
@ -328,10 +334,39 @@ const openCRLogin = () => {
|
||||
backgroundColor: "#111111"
|
||||
})
|
||||
|
||||
interval = setInterval(checkIfLoggedInCR, 1000)
|
||||
intervalcr = setInterval(checkIfLoggedInCR, 1000)
|
||||
}
|
||||
|
||||
const checkIfLoggedInADN = async () => {
|
||||
const { data, error } = await checkAccount('ADN')
|
||||
|
||||
if (error.value) {
|
||||
isLoggedInADN.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (intervaladn) {
|
||||
clearInterval(intervaladn)
|
||||
}
|
||||
|
||||
isLoggedInADN.value = true
|
||||
}
|
||||
|
||||
const openADNLogin = () => {
|
||||
(window as any).myAPI.openWindow({
|
||||
title: "ADN Login",
|
||||
url: isProduction ? 'http://localhost:8079/adnlogin' : 'http://localhost:3000/adnlogin',
|
||||
width: 600,
|
||||
height: 300,
|
||||
backgroundColor: "#111111"
|
||||
})
|
||||
|
||||
intervalcr = setInterval(checkIfLoggedInADN, 1000)
|
||||
}
|
||||
|
||||
|
||||
checkIfLoggedInCR()
|
||||
checkIfLoggedInADN()
|
||||
|
||||
const fetchSearch = async () => {
|
||||
if (!search.value || search.value.length === 0) {
|
||||
@ -341,7 +376,9 @@ const fetchSearch = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
isFetchingResults.value++
|
||||
if (!isFetchingResults.value) {
|
||||
isFetchingResults.value++
|
||||
}
|
||||
|
||||
if (service.value === 'adn') {
|
||||
adnSearchResults.value = await searchADN(search.value)
|
||||
@ -351,7 +388,9 @@ const fetchSearch = async () => {
|
||||
crunchySearchResults.value = await searchCrunchy(search.value)
|
||||
}
|
||||
|
||||
isFetchingResults.value--
|
||||
if (isFetchingResults.value) {
|
||||
isFetchingResults.value--
|
||||
}
|
||||
searchActive.value = true
|
||||
}
|
||||
|
||||
@ -367,6 +406,12 @@ const handleInputChange = () => {
|
||||
debounceFetchSearch()
|
||||
}
|
||||
|
||||
watch(url, () => {
|
||||
if (url.value.length === 0 || !url.value) {
|
||||
searchActive.value = false;
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
;(window as any).myAPI.getFolder().then((result: any) => {
|
||||
path.value = result
|
||||
@ -396,12 +441,21 @@ const selectShow = async (show: any) => {
|
||||
crunchySearchResults.value = []
|
||||
adnSearchResults.value = []
|
||||
searchActive.value = false
|
||||
if (isFetchingResults.value) {
|
||||
isFetchingResults.value--
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedSeason, () => {
|
||||
refetchEpisodes()
|
||||
})
|
||||
|
||||
watch(service, () => {
|
||||
url.value = "",
|
||||
CRselectedShow.value = null,
|
||||
ADNselectedShow.value = null
|
||||
})
|
||||
|
||||
watch(selectedStartEpisode, () => {
|
||||
if (!selectedEndEpisode.value) return
|
||||
if (!episodes.value) return
|
||||
|
59
pages/adnlogin.vue
Normal file
59
pages/adnlogin.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="h-screen overflow-hidden bg-[#111111] flex flex-col p-5 text-white" style="-webkit-app-region: drag">
|
||||
<div class="relative flex flex-row items-center justify-center">
|
||||
<div class="text-2xl">ADN Login</div>
|
||||
</div>
|
||||
<div class="flex flex-col mt-5 gap-3.5 h-full" style="-webkit-app-region: no-drag">
|
||||
<div class="relative flex flex-col">
|
||||
<input v-model="username" type="text" name="text" placeholder="Email" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||
</div>
|
||||
<div class="relative flex flex-col">
|
||||
<input v-model="password" type="password" name="text" placeholder="Password" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex flex-col mt-auto">
|
||||
<button @click="login" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center" style="-webkit-app-region: no-drag">
|
||||
<div class="flex flex-row items-center justify-center transition-all" :class="isLoggingIn ? 'opacity-0' : 'opacity-100'">
|
||||
<div class="text-xl">Login</div>
|
||||
</div>
|
||||
<div class="absolute flex flex-row items-center justify-center gap-1 transition-all" :class="isLoggingIn ? 'opacity-100' : 'opacity-0'">
|
||||
<Icon name="mdi:loading" class="h-6 w-6 animate-spin" />
|
||||
<div class="text-xl">Logging in</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { loginAccount } from '~/components/Crunchyroll/Account'
|
||||
const isProduction = process.env.NODE_ENV !== 'development'
|
||||
|
||||
const username = ref<string>()
|
||||
const password = ref<string>()
|
||||
|
||||
const isLoggingIn = ref<number>(0)
|
||||
|
||||
const login = async () => {
|
||||
isLoggingIn.value++
|
||||
if (!username.value) {
|
||||
isLoggingIn.value--
|
||||
return
|
||||
}
|
||||
if (!password.value) {
|
||||
isLoggingIn.value--
|
||||
return
|
||||
}
|
||||
|
||||
const { data, error } = await loginAccount(username.value, password.value, 'ADN')
|
||||
|
||||
if (error.value) {
|
||||
isLoggingIn.value--
|
||||
return
|
||||
}
|
||||
isLoggingIn.value--
|
||||
close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -378,92 +378,74 @@ import { useFetch } from '../useFetch'
|
||||
// }
|
||||
// }
|
||||
|
||||
export async function adnyLogin(user: string, passw: string) {
|
||||
const cachedData:
|
||||
| {
|
||||
access_token: string
|
||||
refresh_token: string
|
||||
expires_in: number
|
||||
token_type: string
|
||||
scope: string
|
||||
country: string
|
||||
account_id: string
|
||||
profile_id: string
|
||||
}
|
||||
| undefined = server.CacheController.get('adntoken')
|
||||
|
||||
if (!cachedData) {
|
||||
var { data, error } = await adnLoginFetch(user, passw)
|
||||
|
||||
if (error) {
|
||||
messageBox(
|
||||
'error',
|
||||
['Cancel'],
|
||||
2,
|
||||
'Failed to login',
|
||||
'Failed to login to ADN',
|
||||
(error.error as string)
|
||||
)
|
||||
return { data: null, error: error.error }
|
||||
export async function adnLogin(user: string, passw: string) {
|
||||
const cachedData:
|
||||
| {
|
||||
access_token: string
|
||||
refresh_token: string
|
||||
expires_in: number
|
||||
token_type: string
|
||||
scope: string
|
||||
country: string
|
||||
account_id: string
|
||||
profile_id: string
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned null')
|
||||
return { data: null, error: 'ADN returned null' }
|
||||
}
|
||||
|
||||
if (!data.access_token) {
|
||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned malformed data')
|
||||
return { data: null, error: 'ADN returned malformed data' }
|
||||
}
|
||||
|
||||
server.CacheController.set('adntoken', data, data.expires_in - 30)
|
||||
|
||||
return { data: data, error: null }
|
||||
}
|
||||
|
||||
return { data: cachedData, error: null }
|
||||
}
|
||||
|
||||
async function adnLoginFetch(user: string, passw: string) {
|
||||
const headers = {
|
||||
Authorization: 'Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': 'Crunchyroll/3.46.2 Android/13 okhttp/4.12.0'
|
||||
}
|
||||
|
||||
const body: any = {
|
||||
username: user,
|
||||
password: passw,
|
||||
grant_type: 'password',
|
||||
scope: 'offline_access',
|
||||
device_name: 'RMX2170',
|
||||
device_type: 'realme RMX2170'
|
||||
}
|
||||
|
||||
const { data, error } = await useFetch<{
|
||||
access_token: string
|
||||
refresh_token: string
|
||||
expires_in: number
|
||||
token_type: string
|
||||
scope: string
|
||||
country: string
|
||||
account_id: string
|
||||
profile_id: string
|
||||
}>('https://beta-api.crunchyroll.com/auth/v1/token', {
|
||||
type: 'POST',
|
||||
body: new URLSearchParams(body).toString(),
|
||||
header: headers,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
|
||||
| undefined = server.CacheController.get('adntoken')
|
||||
|
||||
if (!cachedData) {
|
||||
var { data, error } = await adnLoginFetch(user, passw)
|
||||
|
||||
if (error) {
|
||||
return { data: null, error: error }
|
||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', error.error as string)
|
||||
return { data: null, error: error.error }
|
||||
}
|
||||
|
||||
|
||||
if (!data) {
|
||||
return { data: null, error: null }
|
||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned null')
|
||||
return { data: null, error: 'ADN returned null' }
|
||||
}
|
||||
|
||||
|
||||
if (!data.accessToken) {
|
||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned malformed data')
|
||||
return { data: null, error: 'ADN returned malformed data' }
|
||||
}
|
||||
|
||||
server.CacheController.set('adntoken', data, 300)
|
||||
|
||||
return { data: data, error: null }
|
||||
}
|
||||
|
||||
return { data: cachedData, error: null }
|
||||
}
|
||||
|
||||
async function adnLoginFetch(user: string, passw: string) {
|
||||
const headers = {
|
||||
'x-target-distribution': 'de',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
const body = {
|
||||
username: user,
|
||||
password: passw,
|
||||
source: 'Web',
|
||||
rememberMe: true
|
||||
}
|
||||
|
||||
const { data, error } = await useFetch<{
|
||||
accessToken: string;
|
||||
}>('https://gw.api.animationdigitalnetwork.fr/authentication/login', {
|
||||
type: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
header: headers,
|
||||
})
|
||||
|
||||
if (error) {
|
||||
return { data: null, error: error }
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return { data: null, error: null }
|
||||
}
|
||||
|
||||
return { data: data, error: null }
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { FastifyReply, FastifyRequest } from "fastify"
|
||||
import { crunchyLogin } from "../crunchyroll/crunchyroll.service"
|
||||
import { addEpisodeToPlaylist, getDownloading, getPlaylist, loggedInCheck, safeLoginData } from "./service.service"
|
||||
import { CrunchyEpisodes } from "../../types/crunchyroll"
|
||||
import { adnLogin } from "../adn/adn.service"
|
||||
|
||||
export async function checkLoginController(request: FastifyRequest<{
|
||||
Params: {
|
||||
@ -48,9 +49,9 @@ export async function loginController(
|
||||
}
|
||||
|
||||
if (params.id === 'ADN') {
|
||||
// const { data, error } = await adnLogin(body.user, body.password)
|
||||
// responseError = error,
|
||||
// responseData = data
|
||||
const { data, error } = await adnLogin(body.user, body.password)
|
||||
responseError = error,
|
||||
responseData = data
|
||||
}
|
||||
|
||||
if (responseError || !responseData) {
|
||||
|
Reference in New Issue
Block a user