mirror of
https://github.com/headporter81/specialsource-homepage-frontend.git
synced 2026-08-08 15:21:11 +09:00
This commit is contained in:
+18
-28
@@ -30,7 +30,7 @@
|
|||||||
<button @click="handleRegister" class="nav-item btn-reg">SIGN UP</button>
|
<button @click="handleRegister" class="nav-item btn-reg">SIGN UP</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="auth-group">
|
<div v-else class="auth-group">
|
||||||
<span class="user-info">ACCESS GRANTED: ADMIN</span>
|
<span class="user-info">ACCESS GRANTED: {{ loggedInUser.toUpperCase() }}</span>
|
||||||
<button @click="handleLogout" class="nav-item btn-logout">LOGOUT</button>
|
<button @click="handleLogout" class="nav-item btn-logout">LOGOUT</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
|
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="isProcessing" class="tui-global-overlay">
|
<div v-if="isProcessing" class="tui-global-overlay">
|
||||||
<TuiProgressBar :progress="overlayProgress" :status="overlayStatus" />
|
<TuiProgressBar :progress="overlayProgress" :status="overlayStatus" :username="loggedInUser" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@@ -256,7 +256,6 @@ const triggerOverlayProcess = (durationMs, initialMsg) => {
|
|||||||
}, stepTime);
|
}, stepTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 🟢 [보안 & 할당량 디버그 강화] 유튜브 로드 모듈
|
|
||||||
const apiKey = 'AIzaSyD51LHwqoY8spjq6rsY_RlhBXzb96j7D6o';
|
const apiKey = 'AIzaSyD51LHwqoY8spjq6rsY_RlhBXzb96j7D6o';
|
||||||
const channelId = 'UC8L92ju0V88s6TcmLPb8Bkg';
|
const channelId = 'UC8L92ju0V88s6TcmLPb8Bkg';
|
||||||
const maxResults = 8;
|
const maxResults = 8;
|
||||||
@@ -273,7 +272,6 @@ const fetchVideos = async () => {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("유튜브 로드 실패 (할당량 초과 또는 키 폐기 가능성):", err);
|
console.error("유튜브 로드 실패 (할당량 초과 또는 키 폐기 가능성):", err);
|
||||||
|
|
||||||
// 1) 아래 CRT 모니터 터미널에 해커 감성으로 에러 경고 사출
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (termInstance.value) {
|
if (termInstance.value) {
|
||||||
termInstance.value.echo(`[[b;red;][WARN]] YOUTUBE API QUOTA EXCEEDED OR KEY REVOKED.`);
|
termInstance.value.echo(`[[b;red;][WARN]] YOUTUBE API QUOTA EXCEEDED OR KEY REVOKED.`);
|
||||||
@@ -281,24 +279,11 @@ const fetchVideos = async () => {
|
|||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
// 2) [★무적 보정 클로킹] 구글 API가 막혔을 때 화면을 꽉 채워줄 고화질 인프라 더미 데이터 주입
|
|
||||||
videos.value = [
|
videos.value = [
|
||||||
{
|
{ id: { videoId: 'dQw4w9WgXcQ' }, snippet: { title: '> ' } },
|
||||||
id: { videoId: 'dQw4w9WgXcQ' }, // Rick Astley (명예의 전당)
|
{ id: { videoId: 'kJQP7kiw5Fk' }, snippet: { title: '> ' } },
|
||||||
snippet: { title: '> [LIVE] SpecialSource Cloud Pipeline Infrastructure Main Cluster Monitoring' }
|
{ id: { videoId: '9bZkp7q19f0' }, snippet: { title: '> ' } },
|
||||||
},
|
{ id: { videoId: 'LXb3EKWsInQ' }, snippet: { title: '> ' } }
|
||||||
{
|
|
||||||
id: { videoId: 'kJQP7kiw5Fk' }, // Lofi
|
|
||||||
snippet: { title: '> [TUTORIAL] Automated Backend CI/CD Deploy Workflow on Ugreen NAS' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: { videoId: '9bZkp7q19f0' },
|
|
||||||
snippet: { title: '> [SECURITY] Injecting JASYPT_ENCRYPTOR_PASSWORD to Docker Runtime' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: { videoId: 'LXb3EKWsInQ' },
|
|
||||||
snippet: { title: '> [DATABASE] PostgreSQL Network Routing & Port 5435 Connection Log' }
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -306,15 +291,23 @@ const fetchVideos = async () => {
|
|||||||
const openVideo = (id) => window.open(`https://www.youtube.com/watch?v=${id}`);
|
const openVideo = (id) => window.open(`https://www.youtube.com/watch?v=${id}`);
|
||||||
const handleRegister = () => alert("회원가입은 현재 관리자 승인제로 운영됩니다.");
|
const handleRegister = () => alert("회원가입은 현재 관리자 승인제로 운영됩니다.");
|
||||||
|
|
||||||
|
// 🟢 [UPGRADE] 로그아웃 시 스토리지 대청소 및 프롬프트 완벽 복구
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
|
localStorage.removeItem('username'); // 👈 [추가] 브라우저에 남은 아이디 파괴
|
||||||
|
|
||||||
authToken.value = null;
|
authToken.value = null;
|
||||||
|
loggedInUser.value = 'anonymous'; // 👈 [추가] 로그인 변수 기본값 리셋
|
||||||
activeMenu.value = 'main';
|
activeMenu.value = 'main';
|
||||||
|
|
||||||
if (termInstance.value) {
|
if (termInstance.value) {
|
||||||
termInstance.value.echo(`\n[[b;red;][ALERT]] SESSION TERMINATED. USER LOGGED OUT.`);
|
termInstance.value.echo(`\n[[b;red;][ALERT]] SESSION TERMINATED. USER LOGGED OUT.`);
|
||||||
|
// 👈 [추가] 하단 CRT 모니터의 아이디 단말기 프롬프트도 anonymous(익명) 상태로 즉시 강제 원상복구
|
||||||
|
termInstance.value.set_prompt(`anonymous@specialsource:~$ `);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 🟢 [UPGRADE] 중복 찌꺼기를 지우고 순서를 정밀 정렬한 로그인 모듈
|
||||||
const handleLoginSubmit = async () => {
|
const handleLoginSubmit = async () => {
|
||||||
if (!loginId.value || !loginPw.value) {
|
if (!loginId.value || !loginPw.value) {
|
||||||
alert("아이디와 비밀번호를 모두 입력해 주세요.");
|
alert("아이디와 비밀번호를 모두 입력해 주세요.");
|
||||||
@@ -344,21 +337,18 @@ const handleLoginSubmit = async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.data && response.data.token) {
|
if (response.data && response.data.token) {
|
||||||
|
// 1) 지저분하게 겹쳐있던 스토리지 세이브 로직 1군데로 최적화 정렬
|
||||||
localStorage.setItem('token', response.data.token);
|
localStorage.setItem('token', response.data.token);
|
||||||
// 🟢 [NEW] 로컬 스토리지와 변수에 로그인한 ID 세이브
|
|
||||||
localStorage.setItem('username', loginId.value);
|
localStorage.setItem('username', loginId.value);
|
||||||
|
|
||||||
|
authToken.value = response.data.token;
|
||||||
loggedInUser.value = loginId.value;
|
loggedInUser.value = loginId.value;
|
||||||
|
|
||||||
overlayProgress.value = 85;
|
overlayProgress.value = 85;
|
||||||
overlayStatus.value = 'Access Granted. Generating JWT Session token...';
|
overlayStatus.value = 'Access Granted. Generating JWT Session token...';
|
||||||
|
|
||||||
localStorage.setItem('token', response.data.token);
|
|
||||||
authToken.value = response.data.token;
|
|
||||||
|
|
||||||
if (termInstance.value) {
|
if (termInstance.value) {
|
||||||
termInstance.value.echo(`[[b;var(--tui-color);][SUCCESS]] ACCESS GRANTED. CREDENTIALS VERIFIED.`);
|
termInstance.value.echo(`[[b;var(--tui-color);][SUCCESS]] ACCESS GRANTED. CREDENTIALS VERIFIED.`);
|
||||||
// 🟢 [NEW] 하단 CRT 터미널 프롬프트도 내 아이디로 동적 변경!
|
|
||||||
termInstance.value.set_prompt(`${loginId.value}@specialsource:~$ `);
|
termInstance.value.set_prompt(`${loginId.value}@specialsource:~$ `);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +374,7 @@ const handleLoginSubmit = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchVideos(); // 초기에 무조건 작동
|
fetchVideos();
|
||||||
|
|
||||||
const globaljQuery = window.$;
|
const globaljQuery = window.$;
|
||||||
if (globaljQuery && terminalRef.value) {
|
if (globaljQuery && terminalRef.value) {
|
||||||
|
|||||||
Reference in New Issue
Block a user