Add QR login support and CCJ code
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
Trenton Zimmer
2026-05-22 16:46:27 -04:00
parent 6ef58a6f66
commit 9edf165198
9 changed files with 185 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
VITE_APP_VERSION="3.1.3"
VITE_APP_VERSION="3.1.4"
VITE_API_URL="http://localhost:8000/"
VITE_API_KEY="your_api_key_should_be_here"
VITE_ASSET_PATH="/assets"

View File

@@ -1,4 +1,4 @@
VITE_APP_VERSION="3.1.3"
VITE_APP_VERSION="3.1.4"
VITE_API_URL="https://restfulsleep.phaseii.network"
VITE_API_KEY="your_api_key_should_be_here"
VITE_ASSET_PATH="https://cdn.phaseii.network/file/PhaseII/web-assets"

View File

@@ -1,6 +1,6 @@
{
"name": "phaseweb3",
"version": "3.1.3",
"version": "3.1.4",
"scripts": {
"dev": "vite --host",
"build": "vite build",

View File

@@ -49,5 +49,6 @@
"3.1.0": ["- (Major) WebUI V3 full release"],
"3.1.1": ["- (Admin) Add more admin stats for users", "- (Minor) Add new greetings"],
"3.1.2": ["- (Major) Add initial code for oAuth pages", "- (Major) Add redirect to target page after login", "- (Minor) Add quick links to navbar", "- (Minor) Add new greetings", "- (Minor) Replace login page background", "- (Minor) Add animation to loading modal", "- (Bugfix) Refactor loading modal", "- (Bugfix) Refactor overlay layer", "- (Bugfix) Optimize main layouts", "- (Bugfix) Fix loading states around site", "- (Bugfix) Optimize news read api calls", "- (Minor) Add simple auth checkers to router, blocking access at webui level"],
"3.1.3": ["- (Major) Add better error popups, add new buttons on errors", "- (Major) Finish initial authorization page for internal apps", "- (Minor) Add more greetings", "- (Bugfix) Fix overlay layer transparency when saving", "- (Bugfix) Fix remaining missing colors"]
"3.1.3": ["- (Major) Add better error popups, add new buttons on errors", "- (Major) Finish initial authorization page for internal apps", "- (Minor) Add more greetings", "- (Bugfix) Fix overlay layer transparency when saving", "- (Bugfix) Fix remaining missing colors"],
"3.1.4": ["- (Major) Add QR game login support", "- (Minor) Add initial CCJ support and events"]
}

View File

@@ -0,0 +1,46 @@
export const CCJOptions = {
1: [
{
id: "allow_global_in_local",
name: "Allow Global Matching in Local",
help: "Allow the server to match-make network wide rather than force a local machine. Not all modes are supported.",
type: "Boolean",
},
{
id: "login_event",
name: "Login Event",
help: "Enable a specific Login Event, separate from the login bonus. Only one can be enabled at a time, and some events may be disabled in newer builds.",
type: "Array",
options: [
{ id: 0, label: "Disabled" },
{ id: 1, label: "Quiz Magic Academy Stamp Book" },
{ id: 2, label: "KAC2023 Stamp Book" },
],
},
{
id: "logout_event",
name: "Logout Event",
help: "Enable a specific Logout Event. Only one can be enabled at a time, and some events may be disabled in newer builds.",
type: "Array",
options: [
{ id: 0, label: "Disabled" },
// { id: 1, label: "Yocchan Ekiden" },
{ id: 2, label: "2023 BINGO BINGO JOKERS" },
{ id: 3, label: "Yocchan business trip Hanami (1)" },
{ id: 4, label: "Yocchan business trip Hanami (2)" },
// { id: 5, label: "O-chan, you can't do it!" },
{ id: 6, label: "Chase Chase Jewelry Leisures (Treasure Hunt)" },
{ id: 7, label: "Yocchan business trip Wedding" },
{ id: 8, label: "Yocchan business trip Chase Sea House" },
// { id: 9, label: "Festival de business trip Yocchan-do" },
{ id: 10, label: "Yocchan business trip Idol" },
],
},
{
id: "info_text",
name: "Information Message",
help: "An announcement on the news banner.",
type: "String",
},
],
};

View File

@@ -14,6 +14,7 @@ import { ReflecBeatOptions } from "@/constants/gameOptions/reflecOptions";
import { SDVXOptions } from "@/constants/gameOptions/sdvxOptions";
import { WinningElevenOptions } from "@/constants/gameOptions/weOptions";
import { SilentScopeOptions } from "@/constants/gameOptions/silentScopeOptions";
import { CCJOptions } from "@/constants/gameOptions/ccjOptions";
import { DDREvents } from "@/constants/scheduledEvents/ddrEvents";
import { IIDXEvents } from "@/constants/scheduledEvents/iidxEvents";
@@ -30,6 +31,7 @@ export class GameConstants {
static DDR = "ddr";
static DDRCLASS = "ddrclass";
static DDROMNI = "ddromni";
static CCJ = "ccj";
static DRUMMANIA = "dm";
static EEMALL = "eemall";
static FUTURETOMTOM = "ftt";
@@ -65,6 +67,8 @@ export class VersionConstants {
static THE_STAR_BISHI_BASHI = 1;
static BISHI_BASHI_CHANNEL = 1;
static CCJ = 1;
static DANCE_EVOLUTION = 1;
static DANCE_RUSH_STARDOM = 1;
@@ -431,6 +435,16 @@ export const gameData = [
noRivals: true,
noScores: true,
},
{
id: GameConstants.CCJ,
name: "Chase Chase Jokers",
icon: null,
cardBG: null,
skip: true,
noRivals: true,
noScores: true,
gameOptions: CCJOptions,
},
{
id: GameConstants.DANCE_EVOLUTION,
name: "DanceEvolution",

View File

@@ -72,6 +72,15 @@ const routes = [
name: "authorize_service",
component: () => import("@/views/Auth/AuthorizeView.vue"),
},
{
meta: {
requiresAuth: true,
title: "Contactless Login",
},
path: "/profile/authorize_game",
name: "authorize_game",
component: () => import("@/views/Auth/AuthorizeGameView.vue"),
},
{
meta: {
requiresAuth: true,

View File

@@ -345,3 +345,27 @@ export async function APIPostAuthClient(clientId) {
throw error;
}
}
export async function APIGetContactless(token) {
const mainStore = useMainStore();
try {
const data = await mainStore.callApi(`/user/contactless/${token}`);
return data?.data;
} catch (error) {
console.log("Error fetching client:", error);
throw error;
}
}
export async function APIPostContactless(token) {
const mainStore = useMainStore();
try {
const data = await mainStore.callApi(`/user/contactless/${token}`, "POST");
return data?.data;
} catch (error) {
console.log("Error posting client:", error);
throw error;
}
}

View File

@@ -0,0 +1,87 @@
<script setup>
import { onMounted, ref } from "vue";
import { useRoute } from "vue-router";
import CardBox from "@/components/CardBox.vue";
import BaseButton from "@/components/BaseButton.vue";
import LayoutGuest from "@/layouts/LayoutGuest.vue";
import { APIGetContactless, APIPostContactless } from "@/stores/api/account.js";
const route = useRoute();
const token = route.query.token;
const tokenData = ref(null);
async function getTokenData() {
const data = await APIGetContactless(token);
if (data?.active == true) {
tokenData.value = data;
}
}
onMounted(async () => {
if (token) {
await getTokenData();
} else {
console.error("No token provided in query parameters.");
}
});
async function submit() {
const data = await APIPostContactless(token);
if (data?.approved == true) {
window.alert("Login approved!");
window.location.href = "/";
}
}
</script>
<template>
<LayoutGuest>
<div class="flex md:min-h-screen md:items-center md:justify-center">
<CardBox
v-if="tokenData !== null"
class="w-full md:w-auto rounded-none md:rounded-xl md:drop-shadow-xl"
has-table
is-auth
>
<div
class="p-4 flex flex-col md:flex-row w-full space-y-2 md:space-y-0 md:space-x-4"
>
<div class="flex flex-col items-center text-wrap h-full md:mt-5">
<div class="flex flex-col items-center text-wrap">
<img src="/favicon.png" class="rounded-full shadow-lg mb-2" />
<h1 class="text-xl"><samp>PhaseII</samp></h1>
<button class="text-sm text-gray-700 dark:text-white/75">
Spinnin' since 2021
</button>
</div>
<hr class="border-r my-1 w-full mb-4" />
<p class="text-lg relative bottom-0">Contactless Login</p>
</div>
<div class="md:border-r" />
<form @submit.prevent="submit()">
<div class="flex flex-col items-center text-wrap">
<h1 class="text-lg md:text-xl mb-2">
Approve Login at
<span class="font-bold">{{ tokenData?.arcade }}</span>
</h1>
<p class="text-md max-w-md wrap-break-word text-center">
You scanned a Contactless Login QR code. Are you really trying
to log in?
</p>
</div>
<div class="flex flex-col gap-2 mt-2">
<BaseButton label="Approve" color="success" type="submit" />
</div>
<hr class="border-t my-4 w-full" />
<div class="flex flex-col gap-2 my-4">
<h2>I changed my mind...</h2>
<BaseButton label="Go back" color="danger" to="/" />
</div>
</form>
</div>
</CardBox>
</div>
</LayoutGuest>
</template>