Initial Commit
Commit pertama, memindahkan repository dari github ke gitea.
This commit is contained in:
commit
13a47fbebf
41 files changed
+12327
No files matched your search
+98
@@ -0,0 +1,98 @@
|
||||
import { cookies } from "next/headers";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { query } from "./db";
|
||||
|
||||
const SESSION_COOKIE_NAME = "aghatis_admin_session";
|
||||
const SESSION_SECRET = process.env.ADMIN_SESSION_SECRET || "aghatis_stellar_session_secret_2026_secure_key";
|
||||
|
||||
interface DBAdminUser {
|
||||
id: number;
|
||||
username: string;
|
||||
password_hash: string;
|
||||
full_name: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export async function verifyUserCredentials(
|
||||
user: string,
|
||||
pass: string
|
||||
): Promise<{ success: boolean; user?: { username: string; role: string; fullName: string } }> {
|
||||
try {
|
||||
const rows = await query<DBAdminUser[]>(
|
||||
"SELECT id, username, password_hash, full_name, role FROM admin_users WHERE username = ? LIMIT 1",
|
||||
[user]
|
||||
);
|
||||
|
||||
if (!rows || rows.length === 0) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
const admin = rows[0];
|
||||
|
||||
// Check bcrypt hash or fallback to direct comparison
|
||||
let isMatch = false;
|
||||
if (admin.password_hash.startsWith("$2b$") || admin.password_hash.startsWith("$2a$")) {
|
||||
isMatch = bcrypt.compareSync(pass, admin.password_hash);
|
||||
} else {
|
||||
isMatch = admin.password_hash === pass;
|
||||
}
|
||||
|
||||
if (!isMatch) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
user: {
|
||||
username: admin.username,
|
||||
role: admin.role,
|
||||
fullName: admin.full_name,
|
||||
},
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Database auth verification error:", err);
|
||||
return { success: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Generate HMAC session token
|
||||
export function createSessionToken(username: string): string {
|
||||
const payload = {
|
||||
username,
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
const json = JSON.stringify(payload);
|
||||
const encoded = Buffer.from(json).toString("base64url");
|
||||
const signature = Buffer.from(`${encoded}:${SESSION_SECRET}`).toString("base64url");
|
||||
return `${encoded}.${signature}`;
|
||||
}
|
||||
|
||||
export function verifySessionToken(token: string): { username: string } | null {
|
||||
try {
|
||||
const [encoded, signature] = token.split(".");
|
||||
if (!encoded || !signature) return null;
|
||||
const expectedSig = Buffer.from(`${encoded}:${SESSION_SECRET}`).toString("base64url");
|
||||
if (signature !== expectedSig) return null;
|
||||
const json = Buffer.from(encoded, "base64url").toString("utf8");
|
||||
const payload = JSON.parse(json);
|
||||
return { username: payload.username };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function isAuthenticated(): Promise<boolean> {
|
||||
const cookieStore = await cookies();
|
||||
const token = cookieStore.get(SESSION_COOKIE_NAME)?.value;
|
||||
if (!token) return false;
|
||||
return verifySessionToken(token) !== null;
|
||||
}
|
||||
|
||||
export async function getAuthenticatedUser(): Promise<{ username: string } | null> {
|
||||
const cookieStore = await cookies();
|
||||
const token = cookieStore.get(SESSION_COOKIE_NAME)?.value;
|
||||
if (!token) return null;
|
||||
return verifySessionToken(token);
|
||||
}
|
||||
|
||||
export { SESSION_COOKIE_NAME };
|
||||
@@ -0,0 +1,31 @@
|
||||
import mysql from "mysql2/promise";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var mysqlPool: mysql.Pool | undefined;
|
||||
}
|
||||
|
||||
const pool =
|
||||
global.mysqlPool ||
|
||||
mysql.createPool({
|
||||
host: process.env.DB_HOST || "103.155.224.244",
|
||||
port: Number(process.env.DB_PORT) || 3306,
|
||||
user: process.env.DB_USER || "root",
|
||||
password: process.env.DB_PASSWORD || "hqn9OY2pJx1oYRYJoVrC0Q64sZj8k3W3ZpoVcsKAmv1DFqO9u0DIMGCkjjXEjLaB",
|
||||
database: process.env.DB_NAME || "aghatis_studio_db",
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
queueLimit: 0,
|
||||
connectTimeout: 10000,
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
global.mysqlPool = pool;
|
||||
}
|
||||
|
||||
export default pool;
|
||||
|
||||
export async function query<T = unknown>(sql: string, params?: unknown[]): Promise<T> {
|
||||
const [rows] = await pool.query(sql, params);
|
||||
return rows as T;
|
||||
}
|
||||
Reference in new issue
Block a user