wip: 디버그 코드 추가

This commit is contained in:
2026-02-17 19:12:28 +09:00
parent f2547fe207
commit 1b08aa0c58
4 changed files with 112 additions and 59 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
import type { AutoLoginFailed, AutoLoginNonceResponse, AutoLoginResponse, LoginFailed, LoginResponse } from "./defs/API/Login"; import type { AutoLoginFailed, AutoLoginNonceResponse, AutoLoginResponse, LoginFailed, LoginResponse } from "./defs/API/Login";
import { APIPathGen } from "./util/APIPathGen"; import { APIPathGen } from "./util/APIPathGen";
import { callSammoAPI, extractHttpMethod, GET, POST, type APICallT, type APITail, type InvalidResponse, type RawArgType, type ValidResponse } from "./util/callSammoAPI"; import { callSammoAPI, extractHttpMethod, POST, type APICallT, type APITail, type InvalidResponse, type RawArgType, type ValidResponse } from "./util/callSammoAPI";
export type { ValidResponse, InvalidResponse }; export type { ValidResponse, InvalidResponse };
const apiRealPath = { const apiRealPath = {
@@ -18,7 +18,7 @@ const apiRealPath = {
hashedToken: string, hashedToken: string,
token_id: number, token_id: number,
}, AutoLoginResponse, AutoLoginFailed>, }, AutoLoginResponse, AutoLoginFailed>,
ReqNonce: GET as APICallT<undefined, AutoLoginNonceResponse, AutoLoginFailed> ReqNonce: POST as APICallT<undefined, AutoLoginNonceResponse, AutoLoginFailed>
}, },
} as const; } as const;
@@ -30,4 +30,4 @@ export const SammoRootAPI = APIPathGen(apiRealPath, (path: string[], tail: APITa
} }
return callSammoAPI(method, path.join('/'), args, pathParam); return callSammoAPI(method, path.join('/'), args, pathParam);
}; };
}); });
+68 -56
View File
@@ -40,7 +40,7 @@ function getToken(): [number, string] | undefined {
console.log('no token'); console.log('no token');
return; return;
} }
const tokenItems = JSON.parse(trialToken) as [number, [number, string], string]; const tokenItems = JSON.parse(trialToken) as [number, [number, string], number];
if (tokenItems[0] != TOKEN_VERSION) { if (tokenItems[0] != TOKEN_VERSION) {
console.log(tokenItems); console.log(tokenItems);
resetToken(); resetToken();
@@ -55,61 +55,73 @@ function resetToken() {
localStorage.removeItem(LOGIN_TOKEN_KEY); localStorage.removeItem(LOGIN_TOKEN_KEY);
} }
async function tryAutoLogin() { async function tryAutoLogin() {
try { try {
const tokenInfo = getToken(); const tokenInfo = getToken();
if (!tokenInfo) { if (!tokenInfo) {
return; return;
} }
const [tokenID, token] = tokenInfo; const [tokenID, token] = tokenInfo;
const result = await SammoRootAPI.Login.ReqNonce(undefined, true); for (let attempt = 0; attempt < 2; attempt++) {
const reqNonceStartAt = Date.now();
if (!result) { const nonceResult = await SammoRootAPI.Login.ReqNonce(undefined, true);
//api 에러.
return; if (!nonceResult) {
} //api 에러.
return;
if (!result.result) { }
resetToken();
return; if (!nonceResult.result) {
} resetToken();
return;
const nonce = result.loginNonce; }
console.debug('try auto login with token', tokenID, token, nonce);
const nonce = nonceResult.loginNonce;
const hashedToken = sha512(token + nonce); console.debug(
const loginResult = await SammoRootAPI.Login.LoginByToken({ 'try auto login with token',
'hashedToken': hashedToken, tokenID,
'token_id': tokenID, `attempt:${attempt + 1}`,
}, true); `reqNonceElapsed:${Date.now() - reqNonceStartAt}ms`
);
if (!loginResult.result) {
if (!loginResult.silent) { const hashedToken = sha512(token + nonce);
alert(loginResult.reason); const loginResult = await SammoRootAPI.Login.LoginByToken({
} 'hashedToken': hashedToken,
console.error(loginResult.reason); 'token_id': tokenID,
return; }, true);
}
if (!loginResult.result) {
if (loginResult.nextToken) { if (loginResult.reason === '자동 로그인: 절차 오류' && attempt === 0) {
regNextToken(loginResult.nextToken); console.warn('auto login failed by procedure error. retrying once.');
} await delay(150);
window.location.href = "./"; continue;
}
}
catch (e) { if (!loginResult.silent) {
if (isString(e)) { alert(loginResult.reason);
alert(e); }
} console.error(loginResult.reason);
console.error(e); return;
return; }
}
if (loginResult.nextToken) {
regNextToken(loginResult.nextToken);
} }
window.location.href = "./";
return;
}
}
catch (e) {
if (isString(e)) {
alert(e);
}
console.error(e);
return;
}
}
function getOAuthToken(mode: string, scope_list?: string[] | string) { function getOAuthToken(mode: string, scope_list?: string[] | string) {
if (mode === undefined) { if (mode === undefined) {
mode = 'login'; mode = 'login';
+28
View File
@@ -13,6 +13,8 @@ use sammo\TimeUtil;
use sammo\Util; use sammo\Util;
use sammo\Validator; use sammo\Validator;
use function sammo\logError;
class LoginByToken extends LoginByID class LoginByToken extends LoginByID
{ {
static array $sensitiveArgs = ['hashedToken']; static array $sensitiveArgs = ['hashedToken'];
@@ -42,6 +44,32 @@ class LoginByToken extends LoginByID
$loginNonce = $session->loginNonce ?? null; $loginNonce = $session->loginNonce ?? null;
$loginNonceExpired = $session->loginNonceExpired ?? null; $loginNonceExpired = $session->loginNonceExpired ?? null;
if (!is_string($loginNonce) || !is_string($loginNonceExpired)) { if (!is_string($loginNonce) || !is_string($loginNonceExpired)) {
logError(
'AutoLoginProcedureError',
Json::encode([
'phase' => 'missing_nonce',
'sid' => session_id(),
'cookie_sid' => $_COOKIE[session_name()] ?? null,
'checked_at' => TimeUtil::now(true),
'host' => gethostname() ?: php_uname('n'),
'php' => PHP_VERSION,
'session_status' => session_status(),
'session_save_handler' => ini_get('session.save_handler') ?: null,
'session_save_path' => ini_get('session.save_path') ?: null,
'session_use_strict_mode' => ini_get('session.use_strict_mode') ?: null,
'session_cookie_samesite' => ini_get('session.cookie_samesite') ?: null,
'session_cookie_secure' => ini_get('session.cookie_secure') ?: null,
'request_method' => $_SERVER['REQUEST_METHOD'] ?? null,
'request_uri' => $_SERVER['REQUEST_URI'] ?? null,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
'token_id' => $this->args['token_id'] ?? null,
'nonce_type' => gettype($loginNonce),
'nonce_expired_type' => gettype($loginNonceExpired),
'reqnonce_context' => $session->loginNonceDebug ?? null,
]),
__FILE__,
[]
);
return '자동 로그인: 절차 오류'; return '자동 로그인: 절차 오류';
} }
+13
View File
@@ -32,6 +32,19 @@ class ReqNonce extends BaseAPI
$loginNonceExpired = TimeUtil::nowAddSeconds(2); $loginNonceExpired = TimeUtil::nowAddSeconds(2);
$session->loginNonce = $loginNonce; $session->loginNonce = $loginNonce;
$session->loginNonceExpired = $loginNonceExpired; $session->loginNonceExpired = $loginNonceExpired;
$session->loginNonceDebug = Json::encode([
'phase' => 'issue_nonce',
'sid' => session_id(),
'cookie_sid' => $_COOKIE[session_name()] ?? null,
'issued_at' => TimeUtil::now(true),
'host' => gethostname() ?: php_uname('n'),
'php' => PHP_VERSION,
'session_save_handler' => ini_get('session.save_handler') ?: null,
'session_save_path' => ini_get('session.save_path') ?: null,
'session_use_strict_mode' => ini_get('session.use_strict_mode') ?: null,
'session_cookie_samesite' => ini_get('session.cookie_samesite') ?: null,
'session_cookie_secure' => ini_get('session.cookie_secure') ?: null,
]);
return [ return [
'result' => true, 'result' => true,
'loginNonce' => $loginNonce, 'loginNonce' => $loginNonce,