Init Gitea

This commit is contained in:
dqj
2025-10-06 21:31:13 +09:00
commit c879b8de12
60 changed files with 41314 additions and 0 deletions

399
views/login.html Normal file
View File

@@ -0,0 +1,399 @@
<!DOCTYPE html>
<html
lang="en-US"
class="light-style customizer-hide"
>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>
<title>Login page - SisAi world </title>
<meta name="description" id="site_desc" content="" />
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="files/favicon.ico" />
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet"
/>
<!-- Icons. Uncomment required icon fonts -->
<!-- link rel="stylesheet" href="../assets/vendor/fonts/boxicons.css" / -->
<!-- Core CSS -->
<link rel="stylesheet" href="files/core.css" class="template-customizer-core-css" />
<link rel="stylesheet" href="files/theme-default.css" class="template-customizer-theme-css" />
<link rel="stylesheet" href="files/demo.css" />
<!-- Vendors CSS -->
<link rel="stylesheet" href="files/perfect-scrollbar.css" />
<!-- Page CSS -->
<!-- Page -->
<link rel="stylesheet" href="files/page-auth.css" />
<!-- Helpers -->
<script src="files/helpers.js"></script>
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
<script src="files/config.js"></script>
<script src="files/jquery.js"></script>
<script src="files/popper.js"></script>
<script src="files/bootstrap.js"></script>
<script src="files/perfect-scrollbar.js"></script>
<script src="files/menu.js"></script>
<script src="files/main.js"></script>
<link rel="stylesheet" href="files/spinner.css" />
<script src="files/amipro_utils.js?v=20230414"></script>
<script>
const i18n_messages = new Map();
lang_map = new Map();
lang_map.set("en-US", "System error occurred. Please try again later");
lang_map.set("zh-CN", "系统出现错误,请稍后重试。");
lang_map.set("ja", "システムエラーが発生しました。後でもう一度お試しください");
i18n_messages.set("msg_sys_err", lang_map);
var lang_map = new Map();
lang_map.set("en-US", "Welcome to SisAi world!");
lang_map.set("zh-CN", "欢迎来到SisAi世界");
lang_map.set("ja", "SisAiワールドへようこそ");
i18n_messages.set("msg_welcome", lang_map);
lang_map = new Map();
lang_map.set("en-US", "EMAIL ADDRESS");
lang_map.set("zh-CN", "邮件地址");
lang_map.set("ja", "メールアドレス");
i18n_messages.set("msg_uid", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Input correct Email address, please!");
lang_map.set("zh-CN", "请输入准确邮件地址!");
lang_map.set("ja", "メールアドレスを正しく入力してください!");
i18n_messages.set("msg_uid_input", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Input password, please!");
lang_map.set("zh-CN", "请输入密码!");
lang_map.set("ja", "パスワードを入力してください!");
i18n_messages.set("msg_pw_input", lang_map);
lang_map = new Map();
lang_map.set("en-US", "PASSWORD");
lang_map.set("zh-CN", "用户密码");
lang_map.set("ja", "パスワード");
i18n_messages.set("msg_pw", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Login");
lang_map.set("zh-CN", "登 录");
lang_map.set("ja", "ログイン");
i18n_messages.set("title_fido2_login", lang_map);
lang_map = new Map();
lang_map.set("en-US", "The account or password is incorrect, please try again.");
lang_map.set("zh-CN", "账号或密码错误,请重试。");
lang_map.set("ja", "アカウントまたはパスワードが間違っています。再試行してください");
i18n_messages.set("login_err_retry", lang_map);
lang_map = new Map();
lang_map.set("zh-CN", "免费创建账号");
lang_map.set("ja", "無料でアカウントを作成");
lang_map.set("en-US", "Create free account");
i18n_messages.set("title_new_account", lang_map);
lang_map = new Map();
lang_map.set("zh-CN", "忘记密码");
lang_map.set("ja", "パスワードを忘れた場合");
lang_map.set("en-US", "Forgot password");
i18n_messages.set("title_reentry_pw", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Sent register email from support@amipro.me.\n"+
"Please check your email and click the link to register your account.\n"+
"Please check spam folder if you can't find the email.");
lang_map.set("zh-CN", "已经从 support@amipro.me 发送创建新账号邮件到您的邮箱,\n请查收邮件并点击邮件中的链接来创建新账号。\n"+
"如果您没有收到邮件,请检查垃圾邮件文件夹。");
lang_map.set("ja", "support@amipro.meからアカウント作成メールを送信しました、\n"+
"メールを確認し、リンクをクリックしてアカウントを作成してください。\n"+
"メールが見つからない場合は、迷惑メール フォルダを確認してください。");
i18n_messages.set("title_sent_reg_email", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Sent re-enter password email from support@amipro.me.\n"+
"Please check your email and click the link to re-enter your password.\n"+
"Please check spam folder if you can't find the email.");
lang_map.set("zh-CN", "已经从 support@amipro.me 发送重置密码邮件到您的邮箱,\n请查收邮件并点击邮件中的链接来重新设置您的密码。\n"+
"如果您没有收到邮件,请检查垃圾邮件文件夹。");
lang_map.set("ja", "support@amipro.meからパスワード設定メールを送信しました、\n"+
"メールを確認し、リンクをクリックしてパスワードを再設定してください。\n"+
"メールが見つからない場合は、迷惑メール フォルダを確認してください。");
i18n_messages.set("title_sent_pw_email", lang_map);
lang_map = new Map();
lang_map.set("en-US", "System error, please try again later.");
lang_map.set("zh-CN", "系统错误,请稍后重试。");
lang_map.set("ja", "システムエラーが発生しました。しばらくしてもう一度お試しください。");
i18n_messages.set("title_syserr_retry", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Contact us");
lang_map.set("zh-CN", "联系我们");
lang_map.set("ja", "お問い合わせ");
i18n_messages.set("title_contact", lang_map);
window.onload = async function() {
setI18NText(i18n_messages)
await logout();
sessionStorage.clear();
}
async function logout() {
try{
var response = await fetch("/logout", {
method: "POST",
cache: "no-cache",
headers: {
"Content-Type": "application/json"
}
});
}catch(err){
alert(getI18NText(i18n_messages, 'msg_sys_err'));
}finally{
hideSpinner();
}
}
function checkInput(){
const uid = $('#uid').val().trim()
if(!checkEmailFormat(uid)){
alert($('#msg_uid_input').html())
return false;
}
const pw = $('#password').val().trim()
if(!pw || 0>=pw.length){
alert($('#msg_pw_input').html())
return false;
}
return true;
}
function checkEmailFormat(email){
if(!email || 0>=email.length)return false;
if(!email.match(/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/))return false;
return true;
}
var is_reset_pw = false;
async function createAccount(reset_pw){
is_reset_pw = reset_pw;
var email = $('#uid').val().trim()
if(!email || !checkEmailFormat(email)){
email = prompt(getI18NText(i18n_messages, 'msg_uid'));
if (!email) return;
if(!checkEmailFormat(email)){
alert(getI18NText(i18n_messages, 'msg_uid_input'));
return;
}
}
showSpinner();
email = email.trim()
try{
const response = await fetch("/sendregmail", {
method: "POST",
cache: "no-cache",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({email: email, language: navigator.language})
})
hideSpinner();
if(response.status == 200){
const resp = await response.json();
if (resp.status!='OK') {
alert(getI18NText(i18n_messages, 'title_syserr_retry'));
}else{
if(is_reset_pw){
alert(getI18NText(i18n_messages, 'title_sent_pw_email'));
}else{
alert(getI18NText(i18n_messages, 'title_sent_reg_email'));
}
}
}else{
alert(getI18NText(i18n_messages, 'title_syserr_retry'));
}
}catch(err){
alert(getI18NText(i18n_messages, 'msg_sys_err'));
}finally{
hideSpinner();
}
}
function showSpinner() {
$('#title_fido2_login').prop('disabled', true);
$('#title_new_account').prop('disabled', true);
$('#title_reentry_pw').prop('disabled', true);
document.getElementById("spinner").style.display = "block";
}
function hideSpinner() {
$('#title_fido2_login').prop('disabled', false);
$('#title_new_account').prop('disabled', false);
$('#title_reentry_pw').prop('disabled', false);
document.getElementById("spinner").style.display = "none";
}
async function authenticate(){
showSpinner();
var email = $('#uid').val().trim()
var pw = $('#password').val().trim()
if(!email || 0>=email.length){
alert($('#msg_uid_input').html())
hideSpinner();
return;
}else if(!pw || 0>=pw.length){
alert($('#msg_pw_input').html())
hideSpinner();
return;
}
email = email.toLowerCase();
try{
const response = await fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({email: email, pwd: pw}),
cache: "no-cache"
})
if(response.status == 200){
const resp = await response.json();
if (resp.status!='OK') {
alert(getI18NText(i18n_messages, 'login_err_retry'));
hideSpinner();
}else{
const nm = getI18NJsonText(resp.nickname);
sessionStorage.setItem('nickname', nm);
sessionStorage.setItem('email', email);
sessionStorage.setItem('uid', resp.uid);
window.location.href = "top.html";
}
}
}catch(err){
alert(getI18NText(i18n_messages, 'msg_sys_err'));
}finally{
hideSpinner();
}
}
</script>
</head>
<body>
<!-- Content -->
<div class="container-xxl">
<div class="authentication-wrapper authentication-basic container-p-y">
<div class="authentication-inner">
<!-- Register -->
<div class="card">
<div class="card-body">
<!-- Logo -->
<div class="app-brand justify-content-center">
<a href="https://www.amiPro.me/" class="app-brand-link gap-2">
<img style="width:160px;" src="files/favicon.ico"/>
</a>
</div>
<!-- /Logo -->
<h4 class="mb-2" id="msg_welcome">Welcome to SisAi world!</h4>
<p class="mb-4" id="msg_intro"></p>
<div id="msg_uid_input" style="display:none;">Input User ID, please!</div>
<div id="msg_pw_input" style="display:none;">Input User ID, please!</div>
<form class="mb-3" action="javascript:authenticate();" method="POST"> <!--onsubmit="return checkInput();" -->
<div class="mb-3">
<label for="uid" class="form-label" id="msg_uid" name="uid">User ID</label>
<input
type="text"
class="form-control"
id="uid"
name="uid"
placeholder="Enter your email address"
autofocus
/>
</div>
<div class="mb-3 form-password-toggle">
<div class="d-flex justify-content-between">
<label class="form-label" for="password" id="msg_pw">Password</label>
</div>
<div class="input-group input-group-merge">
<input
type="password"
id="password"
class="form-control"
name="password"
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
aria-describedby="password"
/>
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
<div class="mb-3">
<button class="btn btn-primary d-grid w-100" id="title_fido2_login">Sign in</button>
</div>
</form>
<p class="text-center" id="fido_btn">
<a href="javascript:createAccount(false);">
<span id="title_new_account">Create account</span>
</a>
</p>
<p class="text-center" id="fido_btn">
<a href="javascript:createAccount(true);">
<span id="title_reentry_pw">Re-entry password</span>
</a>
</p>
<div style="margin-left: 60%;">
<a
href="mailto:support@amipro.me?subject=contact"
target="_blank"
class="footer-link me-4"
id="title_contact"
>Contact</a
>
</div>
</div>
</div>
<!-- /Register -->
</div>
</div>
</div>
<div id="spinner" class="spinner">
<div class="spinner-icon"></div>
</div>
<!-- / Content -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
</body>
</html>