forked from alterminal/alterminal
修正 .gitignore:alterminal 模式誤忽略 cmd/alterminal,補提交 main package
This commit is contained in:
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
# Binaries
|
# Binaries(/ 錨定僅忽略根目錄執行檔;未錨定的 alterminal 會連
|
||||||
alterminal
|
# cmd/alterminal 原始碼目錄一併忽略)
|
||||||
|
/alterminal
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
# Build tools (Tailwind standalone CLI,下載方式見 README)
|
# Build tools (Tailwind standalone CLI,下載方式見 README)
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
|
||||||
|
"alterminal/internal/admin"
|
||||||
|
"alterminal/internal/auth"
|
||||||
|
"alterminal/internal/cli"
|
||||||
|
"alterminal/internal/oidc"
|
||||||
|
"alterminal/internal/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
cli.Run(os.Args[1:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := store.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("database: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// issuer 須為含 scheme 的絕對 URL 且不含尾斜線(OIDC Discovery 1.0
|
||||||
|
// §3:issuer 字串與簽入 token 的 iss claim 必須完全一致),統一去除
|
||||||
|
// 尾斜線以容錯。
|
||||||
|
issuer := strings.TrimSuffix(store.EnvOr("ISSUER", "http://localhost:8080"), "/")
|
||||||
|
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Use(middleware.Logger)
|
||||||
|
r.Use(middleware.Recoverer)
|
||||||
|
|
||||||
|
r.Get("/", auth.AccountPageHandler(db))
|
||||||
|
|
||||||
|
r.Get("/users/{name}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Hello, " + chi.URLParam(r, "name") + "!"))
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Get("/.well-known/openid-configuration", oidc.DiscoveryHandler(issuer))
|
||||||
|
r.Get("/.well-known/jwks.json", oidc.JWKSHandler(db))
|
||||||
|
|
||||||
|
r.Get("/login", auth.LoginPageHandler(db))
|
||||||
|
r.Post("/login", auth.LoginHandler(db))
|
||||||
|
// RP-Initiated Logout 1.0 §2:登出端點須支援 GET 與 POST。不帶 RP
|
||||||
|
// 參數的 POST(側欄登出表單、JSON API)由 handler 內部委由
|
||||||
|
// auth.LogoutHandler 處理,行為不變。
|
||||||
|
r.Get("/logout", oidc.LogoutHandler(db, issuer))
|
||||||
|
r.Post("/logout", oidc.LogoutHandler(db, issuer))
|
||||||
|
|
||||||
|
// 更新密碼(登入者自助變更):驗證目前密碼後於交易內更新並撤銷全部
|
||||||
|
// Session,再輪替目前瀏覽器的 Session(其他裝置立即登出)。
|
||||||
|
r.Get("/password", auth.PasswordPageHandler(db))
|
||||||
|
r.Post("/password", auth.PasswordChangeHandler(db))
|
||||||
|
|
||||||
|
// OIDC 授權碼流程(RFC 6749 §4.1.1 + OIDC Core §3.1)。
|
||||||
|
r.Get("/authorize", oidc.AuthorizeHandler(db))
|
||||||
|
r.Post("/authorize", oidc.AuthorizeHandler(db))
|
||||||
|
r.Post("/token", oidc.TokenHandler(db, issuer))
|
||||||
|
r.Get("/userinfo", oidc.UserInfoHandler(db, issuer))
|
||||||
|
r.Post("/userinfo", oidc.UserInfoHandler(db, issuer))
|
||||||
|
|
||||||
|
r.Get("/admin/keys", admin.KeysPageHandler(db))
|
||||||
|
r.Post("/admin/keys", admin.KeysCreateHandler(db))
|
||||||
|
r.Post("/admin/keys/{id}/retire", admin.KeysRetireHandler(db))
|
||||||
|
|
||||||
|
r.Get("/admin/applications", admin.ApplicationsPageHandler(db))
|
||||||
|
r.Get("/admin/applications/new", admin.ApplicationNewPageHandler(db))
|
||||||
|
r.Post("/admin/applications/new", admin.ApplicationsCreateHandler(db))
|
||||||
|
r.Get("/admin/applications/{id}", admin.ApplicationEditPageHandler(db))
|
||||||
|
r.Post("/admin/applications/{id}", admin.ApplicationUpdateHandler(db))
|
||||||
|
r.Post("/admin/applications/{id}/secret", admin.ApplicationsRotateSecretHandler(db))
|
||||||
|
r.Post("/admin/applications/{id}/delete", admin.ApplicationsDeleteHandler(db))
|
||||||
|
|
||||||
|
r.Handle("/static/*", auth.StaticHandler())
|
||||||
|
|
||||||
|
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
w.Write([]byte("db: " + err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := sqlDB.Ping(); err != nil {
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
w.Write([]byte("db: " + err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write([]byte("ok"))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 未匹配任何路由的路徑(不分方法)輸出自訂 404 頁。
|
||||||
|
r.NotFound(auth.NotFoundHandler)
|
||||||
|
|
||||||
|
if err := http.ListenAndServe(":8080", r); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user