chore(env): add bundled test accounts and seed admin
这个提交包含在:
16
.env
普通文件
16
.env
普通文件
@@ -0,0 +1,16 @@
|
|||||||
|
# ===== CSP 平台(测试账号)=====
|
||||||
|
# 该文件会被仓库提交,仅用于开发/测试环境。
|
||||||
|
|
||||||
|
# 前端默认填充的测试账号
|
||||||
|
NEXT_PUBLIC_TEST_USERNAME=whoami139
|
||||||
|
NEXT_PUBLIC_TEST_PASSWORD=whoami139
|
||||||
|
|
||||||
|
# 后端启动时自动创建的管理员账号(如果不存在)
|
||||||
|
CSP_SEED_ADMIN_USERNAME=admin
|
||||||
|
CSP_SEED_ADMIN_PASSWORD=whoami139
|
||||||
|
|
||||||
|
# 前端请求后端的地址(浏览器侧)
|
||||||
|
NEXT_PUBLIC_API_BASE=http://localhost:8080
|
||||||
|
|
||||||
|
# Next.js 服务端反代用(可选)
|
||||||
|
BACKEND_INTERNAL_URL=http://backend:8080
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
#include <drogon/drogon.h>
|
#include <drogon/drogon.h>
|
||||||
|
|
||||||
#include "csp/app_state.h"
|
#include "csp/app_state.h"
|
||||||
|
#include "csp/services/auth_service.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
@@ -11,6 +13,22 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
csp::AppState::Instance().Init(db_path);
|
csp::AppState::Instance().Init(db_path);
|
||||||
|
|
||||||
|
// Optional seed admin user for dev/test.
|
||||||
|
{
|
||||||
|
const char* u = std::getenv("CSP_SEED_ADMIN_USERNAME");
|
||||||
|
const char* p = std::getenv("CSP_SEED_ADMIN_PASSWORD");
|
||||||
|
if (u && p && std::string(u).size() > 0 && std::string(p).size() > 0) {
|
||||||
|
try {
|
||||||
|
csp::services::AuthService auth(csp::AppState::Instance().db());
|
||||||
|
auth.Register(u, p);
|
||||||
|
LOG_INFO << "seed admin user created: " << u;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// Most likely UNIQUE constraint (already exists)
|
||||||
|
LOG_INFO << "seed admin user skipped: " << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CORS (dev-friendly). In production, prefer reverse proxy same-origin.
|
// CORS (dev-friendly). In production, prefer reverse proxy same-origin.
|
||||||
drogon::app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr& req,
|
drogon::app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr& req,
|
||||||
drogon::AdviceCallback&& cb,
|
drogon::AdviceCallback&& cb,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.backend
|
dockerfile: Dockerfile.backend
|
||||||
@@ -10,6 +12,8 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.frontend
|
dockerfile: Dockerfile.frontend
|
||||||
|
|||||||
@@ -13,8 +13,12 @@ export default function AuthPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [mode, setMode] = useState<"register" | "login">("register");
|
const [mode, setMode] = useState<"register" | "login">("register");
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState(
|
||||||
const [password, setPassword] = useState("");
|
process.env.NEXT_PUBLIC_TEST_USERNAME ?? ""
|
||||||
|
);
|
||||||
|
const [password, setPassword] = useState(
|
||||||
|
process.env.NEXT_PUBLIC_TEST_PASSWORD ?? ""
|
||||||
|
);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [resp, setResp] = useState<AuthResp | null>(null);
|
const [resp, setResp] = useState<AuthResp | null>(null);
|
||||||
|
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户