forked from peas-dev/peas
Compare commits
7 Commits
readme-251
...
develop
| Author | SHA1 | Date |
|---|---|---|
|
|
69d31c1179 | |
|
|
c4e3d4cb9b | |
|
|
bf936548d5 | |
|
|
4a775fc8fb | |
|
|
da896ec168 | |
|
|
f18bddd47e | |
|
|
c587bd5b2b |
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: Bug report.
|
||||||
|
title: "[Bug]: "
|
||||||
|
ref: develop
|
||||||
|
labels:
|
||||||
|
- bug?
|
||||||
|
- bug
|
||||||
|
---
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
Please provide a brief summary of the bug.
|
||||||
|
|
||||||
|
# Confirmed
|
||||||
|
## Versions
|
||||||
|
Please list the versions in which you have seen this bug.
|
||||||
|
|
||||||
|
example
|
||||||
|
```md
|
||||||
|
- v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
# Client Environment
|
||||||
|
Please describe your client environment.
|
||||||
|
User Agent, OS, and model are preferred.
|
||||||
|
for example
|
||||||
|
```md
|
||||||
|
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0
|
||||||
|
Model and OS of the device(s): Windows 11 23H2
|
||||||
|
Browser: Zen Browser (1.16.2b 64bit)
|
||||||
|
Server: http://localhost:3000
|
||||||
|
Peas: v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
# Server Environment(for server admin)
|
||||||
|
Please describe your server environment.
|
||||||
|
for example
|
||||||
|
```md
|
||||||
|
Peas: v1.0.0
|
||||||
|
Node.js: v22.16.0
|
||||||
|
Node.js Server OS and Arch: Windows 11 23H2, x86
|
||||||
|
MariaDB: 10.11.11-MariaDB-0+deb12u1
|
||||||
|
MariaDB Server OS and Arch: Raspbian Lite 64bit, ARM
|
||||||
|
```
|
||||||
|
|
||||||
|
# Expected Behavior
|
||||||
|
Please be specific about the expected behavior.
|
||||||
|
|
||||||
|
# Actual Behavior
|
||||||
|
Please be specific about the actual behavior.
|
||||||
|
|
||||||
|
# Steps to Reproduce
|
||||||
|
Please clearly describe how to reproduce it.
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: Suggest a new feature.
|
||||||
|
title: "[Feature]: "
|
||||||
|
ref: develop
|
||||||
|
labels:
|
||||||
|
- feature
|
||||||
|
---
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
Please provide a brief summary of the feature.
|
||||||
|
|
||||||
|
# Purpose
|
||||||
|
Please state your purpose.
|
||||||
|
|
||||||
|
# Development
|
||||||
|
Please choose one of the following:
|
||||||
|
- Community
|
||||||
|
- Development Owner(Last2014)
|
||||||
|
- You
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
name: Adding i18n language
|
||||||
|
about: Adding i18n supported languages.
|
||||||
|
title: "[i18n Add Lang]: "
|
||||||
|
ref: develop
|
||||||
|
labels:
|
||||||
|
- i18n
|
||||||
|
- add
|
||||||
|
---
|
||||||
|
|
||||||
|
# Target Language
|
||||||
|
Please enter the target language.
|
||||||
|
for example: Japanese
|
||||||
|
|
||||||
|
# Translation assistance
|
||||||
|
Please choose one of the following:
|
||||||
|
- part
|
||||||
|
- all
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
name: i18n Fixes
|
||||||
|
about: Modifying i18n information.
|
||||||
|
title: "[i18n Fix]: "
|
||||||
|
ref: develop
|
||||||
|
labels:
|
||||||
|
- i18n
|
||||||
|
- update
|
||||||
|
- fix
|
||||||
|
---
|
||||||
|
|
||||||
|
# Information to be corrected
|
||||||
|
## Language
|
||||||
|
English
|
||||||
|
|
||||||
|
## Key
|
||||||
|
`information`
|
||||||
|
|
||||||
|
## Before
|
||||||
|
infomation
|
||||||
|
|
||||||
|
## After
|
||||||
|
information
|
||||||
|
|
||||||
|
## Reason
|
||||||
|
typos
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
name: Bug Fixes
|
||||||
|
about: Bug fixes.
|
||||||
|
title: "[Bug Fix]: "
|
||||||
|
ref: develop
|
||||||
|
labels:
|
||||||
|
- bug?
|
||||||
|
- bug
|
||||||
|
---
|
||||||
|
|
||||||
|
# About that bug
|
||||||
|
Please describe the bug.
|
||||||
|
Please link to any related issues.
|
||||||
|
|
||||||
|
# Changes
|
||||||
|
Please list the changes in bullet points.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
name: Other
|
||||||
|
about: Other Pull Request.
|
||||||
|
ref: develop
|
||||||
|
---
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
Please provide a brief summary of the changes
|
||||||
|
|
||||||
|
# Related Issues
|
||||||
|
If you have any related issues, please enter them here.
|
||||||
|
|
@ -84,3 +84,5 @@ ERR_code_invalid: Incorrect code
|
||||||
ERR_code_not_found: Code not found
|
ERR_code_not_found: Code not found
|
||||||
ERR_user_not_found: User not found
|
ERR_user_not_found: User not found
|
||||||
ERR_password_invalid: Incorrect password
|
ERR_password_invalid: Incorrect password
|
||||||
|
ERR_not_mailverify: Email not verified
|
||||||
|
ERR_auth_failed: Auth failed
|
||||||
|
|
|
||||||
|
|
@ -84,3 +84,5 @@ ERR_code_invalid: コードが正しくありません
|
||||||
ERR_code_not_found: コードが見つかりません
|
ERR_code_not_found: コードが見つかりません
|
||||||
ERR_user_not_found: ユーザーが見つかりません
|
ERR_user_not_found: ユーザーが見つかりません
|
||||||
ERR_password_invalid: パスワードが異なります
|
ERR_password_invalid: パスワードが異なります
|
||||||
|
ERR_not_mailverify: メール認証されていません
|
||||||
|
ERR_auth_failed: 認証に失敗しました
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,6 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Peas is a SNS designed for sharing profiles.",
|
"description": "Peas is a SNS designed for sharing profiles.",
|
||||||
"scripts": {
|
|
||||||
"build:locale": "tsc"
|
|
||||||
},
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"sns",
|
"sns",
|
||||||
"profile"
|
"profile"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
"@types/bcrypt": "^6.0.0",
|
"@types/bcrypt": "^6.0.0",
|
||||||
"@types/nodemailer": "^7.0.2",
|
"@types/nodemailer": "^7.0.2",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
|
"child_process": "^1.0.2",
|
||||||
"daisyui": "^5.1.25",
|
"daisyui": "^5.1.25",
|
||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
"globals": "^16.4.0",
|
"globals": "^16.4.0",
|
||||||
|
|
@ -26,7 +27,6 @@
|
||||||
"nodemailer": "^7.0.6",
|
"nodemailer": "^7.0.6",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"tailwindcss": "^4.1.13",
|
"tailwindcss": "^4.1.13",
|
||||||
"ua-parser-js": "^2.0.5",
|
|
||||||
"url": "^0.11.4",
|
"url": "^0.11.4",
|
||||||
"uuid": "^13.0.0"
|
"uuid": "^13.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -24,7 +24,40 @@ export async function getScopeAPIToken(token: string) {
|
||||||
[token]
|
[token]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (tokenData === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const scope: scope[] = tokenData[0].scope.split(",");
|
const scope: scope[] = tokenData[0].scope.split(",");
|
||||||
|
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function Auth(token: string, scopes: scope[]) {
|
||||||
|
const scope = await getScopeAPIToken(token);
|
||||||
|
if (scope === false)
|
||||||
|
return false;
|
||||||
|
if (scope.indexOf("admin:client") !== -1)
|
||||||
|
return true;
|
||||||
|
if (
|
||||||
|
scope.indexOf("user:client") !== -1 &&
|
||||||
|
!scopes.some(s => s.includes("admin"))
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
if (scopes.sort().toString() === scope.sort().toString())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function isSignin(token: string) {
|
||||||
|
return await getScopeAPIToken(token) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHeaderToken(header: string) {
|
||||||
|
const match = header.match(/^Bearer\s(.+)$/);
|
||||||
|
|
||||||
|
if (match && match.length > 1) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ API.route("/signin", SignInAPI);
|
||||||
import mailverifyAPI from "./mailverify.js";
|
import mailverifyAPI from "./mailverify.js";
|
||||||
API.route("/mailverify", mailverifyAPI);
|
API.route("/mailverify", mailverifyAPI);
|
||||||
|
|
||||||
|
import TimeLine from "./timeline/main.js";
|
||||||
|
API.route("/timelime", TimeLine);
|
||||||
|
|
||||||
import NotFound from "./notfound.js";
|
import NotFound from "./notfound.js";
|
||||||
API.route("*", NotFound);
|
API.route("*", NotFound);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,9 @@ import { getKeys as TurnstileKeys, isEnabled as Turnstile } from "../../lib/turn
|
||||||
import { getConnInfo } from "@hono/node-server/conninfo";
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
||||||
import { compareSync as passwordHashCheck } from "bcrypt";
|
import { compareSync as passwordHashCheck } from "bcrypt";
|
||||||
import { v4 as uuid } from "uuid";
|
import { v4 as uuid } from "uuid";
|
||||||
import MailVerifySend from "../../lib/mailverify.js";
|
|
||||||
import { createAPIToken } from "src/lib/token.js";
|
import { createAPIToken } from "src/lib/token.js";
|
||||||
import { UAParser } from "ua-parser-js";
|
|
||||||
import { setCookie } from "hono/cookie";
|
import { setCookie } from "hono/cookie";
|
||||||
|
import type scope from "../../../types/api/scope.js";
|
||||||
|
|
||||||
const SignInAPI = new Hono();
|
const SignInAPI = new Hono();
|
||||||
|
|
||||||
|
|
@ -26,7 +25,7 @@ SignInAPI.post("/", async (c) => {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
body.username.length < 3 ||
|
body.username.length < 3 ||
|
||||||
body.username.length > 15 ||
|
body.username.length > 20 ||
|
||||||
body.password.length < 8 ||
|
body.password.length < 8 ||
|
||||||
body.password.length > 15
|
body.password.length > 15
|
||||||
) {
|
) {
|
||||||
|
|
@ -95,10 +94,22 @@ SignInAPI.post("/", async (c) => {
|
||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user[0].mailverify === 0) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
error: "not_mailverify",
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
if (passwordHashCheck(body.password, user[0].password)) {
|
if (passwordHashCheck(body.password, user[0].password)) {
|
||||||
|
const scope: scope[] = ["user:client"];
|
||||||
|
if (user[0].isAdmin === 1) {
|
||||||
|
scope.push("admin:client");
|
||||||
|
}
|
||||||
|
|
||||||
const token = await createAPIToken(
|
const token = await createAPIToken(
|
||||||
body.username,
|
body.username,
|
||||||
["client"],
|
scope,
|
||||||
"Peas Client"
|
"Peas Client"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ SignUpAPI.post("/", async (c) => {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
body.username.length < 3 ||
|
body.username.length < 3 ||
|
||||||
body.username.length > 15 ||
|
body.username.length > 20 ||
|
||||||
body.password.length < 8 ||
|
body.password.length < 8 ||
|
||||||
body.password.length > 15
|
body.password.length > 15
|
||||||
) {
|
) {
|
||||||
|
|
@ -107,9 +107,18 @@ SignUpAPI.post("/", async (c) => {
|
||||||
|
|
||||||
const passwordHash = await generatePasswordHash(body.password, 10);
|
const passwordHash = await generatePasswordHash(body.password, 10);
|
||||||
|
|
||||||
|
const [otherUser] = await pool.execute<RowDataPacket[]>(
|
||||||
|
"SELECT * FROM users",
|
||||||
|
);
|
||||||
|
|
||||||
|
let isAdmin = 0;
|
||||||
|
if (otherUser.length === 0) {
|
||||||
|
isAdmin = 1;
|
||||||
|
}
|
||||||
|
|
||||||
const [result] = await pool.execute<RowDataPacket[]>(
|
const [result] = await pool.execute<RowDataPacket[]>(
|
||||||
"INSERT INTO `users` (`id`, `password`, `email`, `mailverified`, `time`) VALUES (?, ?, ?, '0', current_timestamp(3))",
|
"INSERT INTO `users` (`id`, `name`, `password`, `email`, `mailverified`, `isAdmin`, `time`) VALUES (?, ?, ?, ?, '0', ?, current_timestamp(3))",
|
||||||
[body.username, passwordHash, body.email],
|
[body.username, body.username, passwordHash, body.email, String(isAdmin)],
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((result as RowDataPacket).affectedRows === 1) {
|
if ((result as RowDataPacket).affectedRows === 1) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { Hono } from "hono";
|
||||||
|
|
||||||
|
const Community = new Hono();
|
||||||
|
|
||||||
|
export default Community;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Hono } from "hono";
|
||||||
|
|
||||||
|
const TimeLine = new Hono();
|
||||||
|
|
||||||
|
import Users from "./users.js";
|
||||||
|
TimeLine.route("/users", Users);
|
||||||
|
|
||||||
|
import Community from "./community.js";
|
||||||
|
TimeLine.route("/community", Community);
|
||||||
|
|
||||||
|
export default TimeLine;
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { Hono } from "hono";
|
||||||
|
import { Auth, getHeaderToken } from "../../../lib/token.js";
|
||||||
|
import pool from "../../../lib/database.js";
|
||||||
|
import type { RowDataPacket } from "mysql2";
|
||||||
|
|
||||||
|
const Users = new Hono();
|
||||||
|
|
||||||
|
Users.post("/", async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
if (!Auth(getHeaderToken(c.req.header("Authorization") ?? ""), ["read:user"])) {
|
||||||
|
return c.json({
|
||||||
|
success: false,
|
||||||
|
error: "auth_failed",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let page = 1;
|
||||||
|
if (
|
||||||
|
typeof body.page === "string" &&
|
||||||
|
!isNaN(Number(body.page)) &&
|
||||||
|
Number(body.page) >= 1
|
||||||
|
) {
|
||||||
|
page = Number(body.page);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [usersData] = await pool.execute<RowDataPacket[]>(
|
||||||
|
"SELECT * FROM users"
|
||||||
|
);
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
for (let i = usersData.length - 1; i < 0; i--) {
|
||||||
|
result.push({
|
||||||
|
username: usersData[i].id,
|
||||||
|
name: usersData[i].name,
|
||||||
|
isAdmin: usersData[i].isAdmin === 1 ? true: false,
|
||||||
|
createAt: usersData[i].time,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
success: true,
|
||||||
|
users: result,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Users;
|
||||||
|
|
@ -4,11 +4,14 @@ import type InfoAPI from "../../../types/api/info";
|
||||||
import Config from "../../../config/peas.config.js";
|
import Config from "../../../config/peas.config.js";
|
||||||
import { getCookie } from "hono/cookie";
|
import { getCookie } from "hono/cookie";
|
||||||
import { Locale } from "../../lib/locale.js";
|
import { Locale } from "../../lib/locale.js";
|
||||||
|
import { isSignin } from "../../lib/token.js";
|
||||||
|
|
||||||
const Home = new Hono();
|
const Home = new Hono();
|
||||||
|
|
||||||
Home.get("/", async (c) => {
|
Home.get("/", async (c) => {
|
||||||
if (getCookie(c, "token") === undefined) return c.redirect("/signin");
|
if (await isSignin(getCookie(c, "token") ?? "") === false) {
|
||||||
|
return c.redirect("/signin");
|
||||||
|
}
|
||||||
|
|
||||||
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ import Icon from "../../components/iconify.js";
|
||||||
import { Locale } from "../../lib/locale.js";
|
import { Locale } from "../../lib/locale.js";
|
||||||
import toComponent from "../../lib/toComponent.js";
|
import toComponent from "../../lib/toComponent.js";
|
||||||
import { getCookie } from "hono/cookie";
|
import { getCookie } from "hono/cookie";
|
||||||
import { getScopeAPIToken } from "../../lib/token.js";
|
import { isSignin } from "../../lib/token.js";
|
||||||
|
|
||||||
const Index = new Hono();
|
const Index = new Hono();
|
||||||
|
|
||||||
Index.get("/", async (c) => {
|
Index.get("/", async (c) => {
|
||||||
if (getCookie(c, "token") !== undefined) {
|
if (await isSignin(getCookie(c, "token") ?? "")) {
|
||||||
const scope = await getScopeAPIToken(getCookie(c, "token") ?? "");
|
return c.redirect("/home");
|
||||||
if (scope !== undefined) return c.redirect("/home");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,13 @@ import { getKeys as getTurnstileKeys, isEnabled as TurnstileIsEnabled } from "..
|
||||||
import Turnstile from "../../components/turnstile.js";
|
import Turnstile from "../../components/turnstile.js";
|
||||||
import { html } from "hono/html";
|
import { html } from "hono/html";
|
||||||
import { getCookie } from "hono/cookie";
|
import { getCookie } from "hono/cookie";
|
||||||
import { getScopeAPIToken } from "../../lib/token.js";
|
import { isSignin } from "../../lib/token.js";
|
||||||
|
|
||||||
const MailVerify = new Hono();
|
const MailVerify = new Hono();
|
||||||
|
|
||||||
MailVerify.get("/", async (c) => {
|
MailVerify.get("/", async (c) => {
|
||||||
if (getCookie(c, "token") !== undefined) {
|
if (await isSignin(getCookie(c, "token") ?? "")) {
|
||||||
const scope = await getScopeAPIToken(getCookie(c, "token") ?? "");
|
return c.redirect("/home");
|
||||||
if (scope !== undefined) return c.redirect("/home");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,13 @@ import Turnstile from "../../components/turnstile.js";
|
||||||
import { getKeys as getTurnstileKeys, isEnabled as TurnstileIsEnabled } from "../../lib/turnstile.js";
|
import { getKeys as getTurnstileKeys, isEnabled as TurnstileIsEnabled } from "../../lib/turnstile.js";
|
||||||
import { html } from "hono/html";
|
import { html } from "hono/html";
|
||||||
import { getCookie } from "hono/cookie";
|
import { getCookie } from "hono/cookie";
|
||||||
import { getScopeAPIToken } from "../../lib/token.js";
|
import { isSignin } from "../../lib/token.js";
|
||||||
|
|
||||||
const SignIn = new Hono();
|
const SignIn = new Hono();
|
||||||
|
|
||||||
SignIn.get("/", async (c) => {
|
SignIn.get("/", async (c) => {
|
||||||
if (getCookie(c, "token") !== undefined) {
|
if (await isSignin(getCookie(c, "token") ?? "")) {
|
||||||
const scope = await getScopeAPIToken(getCookie(c, "token") ?? "");
|
return c.redirect("/home");
|
||||||
if (scope !== undefined) return c.redirect("/home");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,13 @@ import Turnstile from "../../components/turnstile.js";
|
||||||
import { getKeys as getTurnstileKeys, isEnabled as TurnstileIsEnabled } from "../../lib/turnstile.js";
|
import { getKeys as getTurnstileKeys, isEnabled as TurnstileIsEnabled } from "../../lib/turnstile.js";
|
||||||
import { html } from "hono/html";
|
import { html } from "hono/html";
|
||||||
import { getCookie } from "hono/cookie";
|
import { getCookie } from "hono/cookie";
|
||||||
import { getScopeAPIToken } from "../../lib/token.js";
|
import { isSignin } from "../../lib/token.js";
|
||||||
|
|
||||||
const SignUp = new Hono();
|
const SignUp = new Hono();
|
||||||
|
|
||||||
SignUp.get("/", async (c) => {
|
SignUp.get("/", async (c) => {
|
||||||
if (getCookie(c, "token") !== undefined) {
|
if (await isSignin(getCookie(c, "token") ?? "")) {
|
||||||
const scope = await getScopeAPIToken(getCookie(c, "token") ?? "");
|
return c.redirect("/home");
|
||||||
if (scope !== undefined) return c.redirect("/home");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
const InfoReq = await fetch(`${Config.server.origin}/api/info`, {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
type scope =
|
type scope =
|
||||||
"read:user" |
|
"read:user" |
|
||||||
"client";
|
"admin:client" |
|
||||||
|
"user:client";
|
||||||
|
|
||||||
export default scope;
|
export default scope;
|
||||||
|
|
|
||||||
146
pnpm-lock.yaml
146
pnpm-lock.yaml
|
|
@ -10,10 +10,10 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/prompts':
|
'@inquirer/prompts':
|
||||||
specifier: ^7.8.6
|
specifier: ^7.8.6
|
||||||
version: 7.8.6(@types/node@24.5.2)
|
version: 7.8.6(@types/node@24.6.2)
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^24.5.2
|
specifier: ^24.5.2
|
||||||
version: 24.5.2
|
version: 24.6.2
|
||||||
fs:
|
fs:
|
||||||
specifier: 0.0.1-security
|
specifier: 0.0.1-security
|
||||||
version: 0.0.1-security
|
version: 0.0.1-security
|
||||||
|
|
@ -22,7 +22,7 @@ importers:
|
||||||
version: 3.15.1
|
version: 3.15.1
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.9.2
|
specifier: ^5.9.2
|
||||||
version: 5.9.2
|
version: 5.9.3
|
||||||
yaml:
|
yaml:
|
||||||
specifier: ^2.8.1
|
specifier: ^2.8.1
|
||||||
version: 2.8.1
|
version: 2.8.1
|
||||||
|
|
@ -163,8 +163,8 @@ packages:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@types/node@24.5.2':
|
'@types/node@24.6.2':
|
||||||
resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==}
|
resolution: {integrity: sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==}
|
||||||
|
|
||||||
ansi-regex@5.0.1:
|
ansi-regex@5.0.1:
|
||||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||||
|
|
@ -261,13 +261,13 @@ packages:
|
||||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
typescript@5.9.2:
|
typescript@5.9.3:
|
||||||
resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==}
|
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
undici-types@7.12.0:
|
undici-types@7.13.0:
|
||||||
resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==}
|
resolution: {integrity: sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==}
|
||||||
|
|
||||||
wrap-ansi@6.2.0:
|
wrap-ansi@6.2.0:
|
||||||
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||||
|
|
@ -286,132 +286,132 @@ snapshots:
|
||||||
|
|
||||||
'@inquirer/ansi@1.0.0': {}
|
'@inquirer/ansi@1.0.0': {}
|
||||||
|
|
||||||
'@inquirer/checkbox@4.2.4(@types/node@24.5.2)':
|
'@inquirer/checkbox@4.2.4(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/ansi': 1.0.0
|
'@inquirer/ansi': 1.0.0
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/figures': 1.0.13
|
'@inquirer/figures': 1.0.13
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/confirm@5.1.18(@types/node@24.5.2)':
|
'@inquirer/confirm@5.1.18(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/core@10.2.2(@types/node@24.5.2)':
|
'@inquirer/core@10.2.2(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/ansi': 1.0.0
|
'@inquirer/ansi': 1.0.0
|
||||||
'@inquirer/figures': 1.0.13
|
'@inquirer/figures': 1.0.13
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
cli-width: 4.1.0
|
cli-width: 4.1.0
|
||||||
mute-stream: 2.0.0
|
mute-stream: 2.0.0
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
wrap-ansi: 6.2.0
|
wrap-ansi: 6.2.0
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/editor@4.2.20(@types/node@24.5.2)':
|
'@inquirer/editor@4.2.20(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/external-editor': 1.0.2(@types/node@24.5.2)
|
'@inquirer/external-editor': 1.0.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/expand@4.0.20(@types/node@24.5.2)':
|
'@inquirer/expand@4.0.20(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/external-editor@1.0.2(@types/node@24.5.2)':
|
'@inquirer/external-editor@1.0.2(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
chardet: 2.1.0
|
chardet: 2.1.0
|
||||||
iconv-lite: 0.7.0
|
iconv-lite: 0.7.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/figures@1.0.13': {}
|
'@inquirer/figures@1.0.13': {}
|
||||||
|
|
||||||
'@inquirer/input@4.2.4(@types/node@24.5.2)':
|
'@inquirer/input@4.2.4(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/number@3.0.20(@types/node@24.5.2)':
|
'@inquirer/number@3.0.20(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/password@4.0.20(@types/node@24.5.2)':
|
'@inquirer/password@4.0.20(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/ansi': 1.0.0
|
'@inquirer/ansi': 1.0.0
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/prompts@7.8.6(@types/node@24.5.2)':
|
'@inquirer/prompts@7.8.6(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/checkbox': 4.2.4(@types/node@24.5.2)
|
'@inquirer/checkbox': 4.2.4(@types/node@24.6.2)
|
||||||
'@inquirer/confirm': 5.1.18(@types/node@24.5.2)
|
'@inquirer/confirm': 5.1.18(@types/node@24.6.2)
|
||||||
'@inquirer/editor': 4.2.20(@types/node@24.5.2)
|
'@inquirer/editor': 4.2.20(@types/node@24.6.2)
|
||||||
'@inquirer/expand': 4.0.20(@types/node@24.5.2)
|
'@inquirer/expand': 4.0.20(@types/node@24.6.2)
|
||||||
'@inquirer/input': 4.2.4(@types/node@24.5.2)
|
'@inquirer/input': 4.2.4(@types/node@24.6.2)
|
||||||
'@inquirer/number': 3.0.20(@types/node@24.5.2)
|
'@inquirer/number': 3.0.20(@types/node@24.6.2)
|
||||||
'@inquirer/password': 4.0.20(@types/node@24.5.2)
|
'@inquirer/password': 4.0.20(@types/node@24.6.2)
|
||||||
'@inquirer/rawlist': 4.1.8(@types/node@24.5.2)
|
'@inquirer/rawlist': 4.1.8(@types/node@24.6.2)
|
||||||
'@inquirer/search': 3.1.3(@types/node@24.5.2)
|
'@inquirer/search': 3.1.3(@types/node@24.6.2)
|
||||||
'@inquirer/select': 4.3.4(@types/node@24.5.2)
|
'@inquirer/select': 4.3.4(@types/node@24.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/rawlist@4.1.8(@types/node@24.5.2)':
|
'@inquirer/rawlist@4.1.8(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/search@3.1.3(@types/node@24.5.2)':
|
'@inquirer/search@3.1.3(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/figures': 1.0.13
|
'@inquirer/figures': 1.0.13
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/select@4.3.4(@types/node@24.5.2)':
|
'@inquirer/select@4.3.4(@types/node@24.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inquirer/ansi': 1.0.0
|
'@inquirer/ansi': 1.0.0
|
||||||
'@inquirer/core': 10.2.2(@types/node@24.5.2)
|
'@inquirer/core': 10.2.2(@types/node@24.6.2)
|
||||||
'@inquirer/figures': 1.0.13
|
'@inquirer/figures': 1.0.13
|
||||||
'@inquirer/type': 3.0.8(@types/node@24.5.2)
|
'@inquirer/type': 3.0.8(@types/node@24.6.2)
|
||||||
yoctocolors-cjs: 2.1.3
|
yoctocolors-cjs: 2.1.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@inquirer/type@3.0.8(@types/node@24.5.2)':
|
'@inquirer/type@3.0.8(@types/node@24.6.2)':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 24.5.2
|
'@types/node': 24.6.2
|
||||||
|
|
||||||
'@types/node@24.5.2':
|
'@types/node@24.6.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 7.12.0
|
undici-types: 7.13.0
|
||||||
|
|
||||||
ansi-regex@5.0.1: {}
|
ansi-regex@5.0.1: {}
|
||||||
|
|
||||||
|
|
@ -491,9 +491,9 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex: 5.0.1
|
ansi-regex: 5.0.1
|
||||||
|
|
||||||
typescript@5.9.2: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
undici-types@7.12.0: {}
|
undici-types@7.13.0: {}
|
||||||
|
|
||||||
wrap-ansi@6.2.0:
|
wrap-ansi@6.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,12 @@ DROP TABLE IF EXISTS `users`;
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
/*!40101 SET character_set_client = utf8 */;
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
CREATE TABLE `users` (
|
CREATE TABLE `users` (
|
||||||
`id` text NOT NULL,
|
`id` VARCHAR(20) NOT NULL,
|
||||||
|
`name` VARCHAR(50) NOT NULL,
|
||||||
`password` text NOT NULL,
|
`password` text NOT NULL,
|
||||||
`email` text NOT NULL,
|
`email` text NOT NULL,
|
||||||
`mailverified` int(1) NOT NULL DEFAULT 0,
|
`mailverified` int(1) NOT NULL DEFAULT 0,
|
||||||
|
`isAdmin` int(1) NOT NULL DEFAULT 0,
|
||||||
`time` datetime(3) NOT NULL DEFAULT current_timestamp(3),
|
`time` datetime(3) NOT NULL DEFAULT current_timestamp(3),
|
||||||
`num` int(11) NOT NULL AUTO_INCREMENT,
|
`num` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
PRIMARY KEY (`num`),
|
PRIMARY KEY (`num`),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue