diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 2f47b83..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Identity \ No newline at end of file diff --git a/.idea/Identity.iml b/.idea/Passport.iml similarity index 100% rename from .idea/Identity.iml rename to .idea/Passport.iml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 60dc64b..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index c6d5757..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - postgresql - true - org.postgresql.Driver - jdbc:postgresql://localhost:5432/hy_identity - $ProjectFileDir$ - - - postgresql - true - org.postgresql.Driver - jdbc:postgresql://id.solsynth.dev:5432/identity - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index ff8127b..18e9cd7 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..c7f72d7 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + \ No newline at end of file diff --git a/go.mod b/go.mod index 0fdcb20..f28bbb3 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-playground/validator/v10 v10.17.0 github.com/gofiber/contrib/websocket v1.3.0 github.com/gofiber/fiber/v2 v2.52.4 + github.com/gofiber/template/html/v2 v2.1.1 github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/uuid v1.6.0 github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible @@ -40,6 +41,8 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect + github.com/gofiber/template v1.8.3 // indirect + github.com/gofiber/utils v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/s2a-go v0.1.7 // indirect @@ -61,6 +64,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect diff --git a/go.sum b/go.sum index ef8031e..c5a57a0 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,12 @@ github.com/gofiber/contrib/websocket v1.3.0 h1:XADFAGorer1VJ1bqC4UkCjqS37kwRTV04 github.com/gofiber/contrib/websocket v1.3.0/go.mod h1:xguaOzn2ZZ759LavtosEP+rcxIgBEE/rdumPINhR+Xo= github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM= github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= +github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= +github.com/gofiber/template/html/v2 v2.1.1 h1:QEy3O3EBkvwDthy5bXVGUseOyO6ldJoiDxlF4+MJiV8= +github.com/gofiber/template/html/v2 v2.1.1/go.mod h1:2G0GHHOUx70C1LDncoBpe4T6maQbNa4x1CVNFW0wju0= +github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= +github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= @@ -146,6 +152,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= +github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= diff --git a/pkg/cmd/main.go b/pkg/cmd/main.go index d85b6f4..f451f18 100644 --- a/pkg/cmd/main.go +++ b/pkg/cmd/main.go @@ -1,6 +1,8 @@ package main import ( + "git.solsynth.dev/hydrogen/passport/pkg" + "git.solsynth.dev/hydrogen/passport/pkg/i18n" "os" "os/signal" "syscall" @@ -11,7 +13,6 @@ import ( "git.solsynth.dev/hydrogen/passport/pkg/services" "github.com/robfig/cron/v3" - passport "git.solsynth.dev/hydrogen/passport/pkg" "git.solsynth.dev/hydrogen/passport/pkg/database" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -35,6 +36,8 @@ func main() { log.Panic().Err(err).Msg("An error occurred when loading settings.") } + i18n.InitInternationalization() + // Connect to database if err := database.NewGorm(); err != nil { log.Fatal().Err(err).Msg("An error occurred when connect to database.") @@ -72,13 +75,13 @@ func main() { quartz.Start() // Messages - log.Info().Msgf("Identity v%s is started...", passport.AppVersion) + log.Info().Msgf("Passport v%s is started...", pkg.AppVersion) quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit - log.Info().Msgf("Identity v%s is quitting...", passport.AppVersion) + log.Info().Msgf("Passport v%s is quitting...", pkg.AppVersion) quartz.Stop() diff --git a/pkg/embed.go b/pkg/embed.go new file mode 100644 index 0000000..38dd3ff --- /dev/null +++ b/pkg/embed.go @@ -0,0 +1,6 @@ +package pkg + +import "embed" + +//go:embed views/* +var FS embed.FS diff --git a/pkg/i18n/bundle.go b/pkg/i18n/bundle.go new file mode 100644 index 0000000..fc1edcb --- /dev/null +++ b/pkg/i18n/bundle.go @@ -0,0 +1,16 @@ +package i18n + +import ( + jsoniter "github.com/json-iterator/go" + "github.com/nicksnyder/go-i18n/v2/i18n" + "golang.org/x/text/language" +) + +var Bundle *i18n.Bundle + +func InitInternationalization() { + Bundle = i18n.NewBundle(language.English) + Bundle.RegisterUnmarshalFunc("json", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) + Bundle.LoadMessageFileFS(FS, "locale.en.json") + Bundle.LoadMessageFileFS(FS, "locale.zh.json") +} diff --git a/pkg/i18n/embed.go b/pkg/i18n/embed.go new file mode 100644 index 0000000..8f02e11 --- /dev/null +++ b/pkg/i18n/embed.go @@ -0,0 +1,6 @@ +package i18n + +import "embed" + +//go:embed locale.*.json +var FS embed.FS diff --git a/pkg/i18n/locale.en.json b/pkg/i18n/locale.en.json new file mode 100644 index 0000000..ca38155 --- /dev/null +++ b/pkg/i18n/locale.en.json @@ -0,0 +1,7 @@ +{ + "next": "Next", + "username": "Username", + "password": "Password", + "signinTitle": "Sign In", + "signinCaption": "Sign in to Solarpass to explore entire Solar Network. Explore posts, discover communities, talk with your best friends. All these things in the Solar Network!" +} \ No newline at end of file diff --git a/pkg/i18n/locale.zh.json b/pkg/i18n/locale.zh.json new file mode 100644 index 0000000..b63a2b9 --- /dev/null +++ b/pkg/i18n/locale.zh.json @@ -0,0 +1,7 @@ +{ + "next": "下一步", + "username": "用户名", + "password": "密码", + "signinTitle": "登陆", + "signinCaption": "登陆 Solarpass 以探索整个 Solar Network,浏览帖子、探索社区、和你的好朋友聊八卦,一切尽在 Solar Network!" +} diff --git a/pkg/i18n/middleware.go b/pkg/i18n/middleware.go new file mode 100644 index 0000000..3e2d990 --- /dev/null +++ b/pkg/i18n/middleware.go @@ -0,0 +1,15 @@ +package i18n + +import ( + "github.com/gofiber/fiber/v2" + "github.com/nicksnyder/go-i18n/v2/i18n" +) + +func I18nMiddleware(c *fiber.Ctx) error { + accept := c.Get(fiber.HeaderAcceptLanguage) + localizer := i18n.NewLocalizer(Bundle, accept) + + c.Locals("localizer", localizer) + + return c.Next() +} diff --git a/pkg/meta.go b/pkg/meta.go index 6780a6d..e0251b4 100644 --- a/pkg/meta.go +++ b/pkg/meta.go @@ -1,4 +1,4 @@ -package passport +package pkg const ( AppVersion = "1.0.0" diff --git a/pkg/server/startup.go b/pkg/server/startup.go index 08d75f3..c727925 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -1,35 +1,39 @@ package server import ( + "git.solsynth.dev/hydrogen/passport/pkg" + "git.solsynth.dev/hydrogen/passport/pkg/i18n" + "git.solsynth.dev/hydrogen/passport/pkg/server/ui" "github.com/gofiber/contrib/websocket" - "net/http" - "strings" - "time" - - "git.solsynth.dev/hydrogen/passport/pkg/views" "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cache" "github.com/gofiber/fiber/v2/middleware/cors" - "github.com/gofiber/fiber/v2/middleware/filesystem" + "github.com/gofiber/fiber/v2/middleware/favicon" "github.com/gofiber/fiber/v2/middleware/idempotency" "github.com/gofiber/fiber/v2/middleware/logger" + "github.com/gofiber/template/html/v2" jsoniter "github.com/json-iterator/go" "github.com/rs/zerolog/log" "github.com/spf13/viper" + "net/http" + "strings" ) var A *fiber.App func NewServer() { + templates := html.NewFileSystem(http.FS(pkg.FS), ".gohtml") + A = fiber.New(fiber.Config{ DisableStartupMessage: true, EnableIPValidation: true, - ServerHeader: "Hydrogen.Identity", - AppName: "Hydrogen.Identity", + ServerHeader: "Hydrogen.Passport", + AppName: "Hydrogen.Passport", ProxyHeader: fiber.HeaderXForwardedFor, JSONEncoder: jsoniter.ConfigCompatibleWithStandardLibrary.Marshal, JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal, EnablePrintRoutes: viper.GetBool("debug.print_routes"), + Views: templates, + ViewsLayout: "views/index", }) A.Use(idempotency.New()) @@ -54,6 +58,8 @@ func NewServer() { Output: log.Logger, })) + A.Use(i18n.I18nMiddleware) + A.Get("/.well-known", getMetadata) A.Get("/.well-known/openid-configuration", getOidcConfiguration) @@ -120,15 +126,13 @@ func NewServer() { } } - A.Use("/", cache.New(cache.Config{ - Expiration: 24 * time.Hour, - CacheControl: true, - }), filesystem.New(filesystem.Config{ - Root: http.FS(views.FS), - PathPrefix: "dist", - Index: "index.html", - NotFoundFile: "dist/index.html", + A.Use(favicon.New(favicon.Config{ + FileSystem: http.FS(pkg.FS), + File: "views/favicon.png", + URL: "/favicon.png", })) + + ui.MapUserInterface(A) } func Listen() { diff --git a/pkg/server/ui/auth.go b/pkg/server/ui/auth.go new file mode 100644 index 0000000..e7b4697 --- /dev/null +++ b/pkg/server/ui/auth.go @@ -0,0 +1,26 @@ +package ui + +import ( + "github.com/gofiber/fiber/v2" + "github.com/nicksnyder/go-i18n/v2/i18n" +) + +func signinPage(c *fiber.Ctx) error { + localizer := c.Locals("localizer").(*i18n.Localizer) + + next, _ := localizer.LocalizeMessage(&i18n.Message{ID: "next"}) + username, _ := localizer.LocalizeMessage(&i18n.Message{ID: "username"}) + password, _ := localizer.LocalizeMessage(&i18n.Message{ID: "password"}) + title, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinTitle"}) + caption, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinCaption"}) + + return c.Render("views/signin", fiber.Map{ + "i18n": fiber.Map{ + "next": next, + "username": username, + "password": password, + "title": title, + "caption": caption, + }, + }, "views/layouts/auth") +} diff --git a/pkg/server/ui/index.go b/pkg/server/ui/index.go new file mode 100644 index 0000000..9bc372b --- /dev/null +++ b/pkg/server/ui/index.go @@ -0,0 +1,8 @@ +package ui + +import "github.com/gofiber/fiber/v2" + +func MapUserInterface(A *fiber.App) { + pages := A.Group("/").Name("Pages") + pages.Get("/sign-in", signinPage) +} diff --git a/pkg/server/userinfo..go b/pkg/server/userinfo.go similarity index 100% rename from pkg/server/userinfo..go rename to pkg/server/userinfo.go diff --git a/pkg/views/.eslintrc.cjs b/pkg/views/.eslintrc.cjs deleted file mode 100644 index f41350a..0000000 --- a/pkg/views/.eslintrc.cjs +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution") - -module.exports = { - root: true, - extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/eslint-config-typescript", - "@vue/eslint-config-prettier/skip-formatting", - ], - parserOptions: { - ecmaVersion: "latest", - }, -} diff --git a/pkg/views/.eslintrc.js b/pkg/views/.eslintrc.js deleted file mode 100644 index b2d47e8..0000000 --- a/pkg/views/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extends: ["plugin:vue/vue3-recommended"], - rules: { - "vue/multi-word-component-names": "off", - }, -} diff --git a/pkg/views/.gitignore b/pkg/views/.gitignore deleted file mode 100644 index 8ee54e8..0000000 --- a/pkg/views/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -.DS_Store -dist -dist-ssr -coverage -*.local - -/cypress/videos/ -/cypress/screenshots/ - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -*.tsbuildinfo diff --git a/pkg/views/.prettierrc.json b/pkg/views/.prettierrc.json deleted file mode 100644 index 6404b10..0000000 --- a/pkg/views/.prettierrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc", - "semi": false, - "tabWidth": 2, - "singleQuote": false, - "printWidth": 120, - "trailingComma": "all" -} diff --git a/pkg/views/.vscode/extensions.json b/pkg/views/.vscode/extensions.json deleted file mode 100644 index 0449b97..0000000 --- a/pkg/views/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["Vue.volar", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] -} diff --git a/pkg/views/README.md b/pkg/views/README.md deleted file mode 100644 index bdb10ae..0000000 --- a/pkg/views/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# views - -This template should help get you started developing with Vue 3 in Vite. - -## Recommended IDE Setup - -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). - -## Type Support for `.vue` Imports in TS - -TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. - -## Customize configuration - -See [Vite Configuration Reference](https://vitejs.dev/config/). - -## Project Setup - -```sh -npm install -``` - -### Compile and Hot-Reload for Development - -```sh -npm run dev -``` - -### Type-Check, Compile and Minify for Production - -```sh -npm run build -``` - -### Lint with [ESLint](https://eslint.org/) - -```sh -npm run lint -``` diff --git a/pkg/views/embed.go b/pkg/views/embed.go deleted file mode 100644 index bc04fa4..0000000 --- a/pkg/views/embed.go +++ /dev/null @@ -1,6 +0,0 @@ -package views - -import "embed" - -//go:embed all:dist -var FS embed.FS diff --git a/pkg/views/env.d.ts b/pkg/views/env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/pkg/views/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/pkg/views/favicon.png b/pkg/views/favicon.png new file mode 100644 index 0000000..f044b34 Binary files /dev/null and b/pkg/views/favicon.png differ diff --git a/pkg/views/index.gohtml b/pkg/views/index.gohtml new file mode 100644 index 0000000..c0c265f --- /dev/null +++ b/pkg/views/index.gohtml @@ -0,0 +1,10 @@ + + + +{{template "views/partials/header"}} + + +{{embed}} + + + \ No newline at end of file diff --git a/pkg/views/index.html b/pkg/views/index.html deleted file mode 100644 index c61a7b4..0000000 --- a/pkg/views/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Solarpass - - -
- - - diff --git a/pkg/views/layouts/auth.gohtml b/pkg/views/layouts/auth.gohtml new file mode 100644 index 0000000..926a029 --- /dev/null +++ b/pkg/views/layouts/auth.gohtml @@ -0,0 +1,87 @@ + + + +{{template "views/partials/header"}} + + +
+
+ {{embed}} +
+
+ + + + \ No newline at end of file diff --git a/pkg/views/package.json b/pkg/views/package.json deleted file mode 100644 index 2c2ee4a..0000000 --- a/pkg/views/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@hydrogen/passport", - "version": "1.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "run-p type-check \"build-only {@}\" --", - "preview": "vite preview", - "build-only": "vite build", - "type-check": "vue-tsc --build --force", - "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "format": "prettier --write src/" - }, - "dependencies": { - "@fontsource/roboto": "^5.0.12", - "@mdi/font": "^7.4.47", - "@unocss/reset": "^0.58.5", - "dompurify": "^3.0.10", - "marked": "^12.0.1", - "pinia": "^2.1.7", - "universal-cookie": "^7.1.0", - "unocss": "^0.58.5", - "vue": "^3.4.21", - "vue-router": "^4.3.0", - "vuetify": "^3.5.8" - }, - "devDependencies": { - "@rushstack/eslint-patch": "^1.3.3", - "@tsconfig/node20": "^20.1.2", - "@types/dompurify": "^3.0.5", - "@types/node": "^20.11.25", - "@vitejs/plugin-vue": "^5.0.4", - "@vitejs/plugin-vue-jsx": "^3.1.0", - "@vue/eslint-config-prettier": "^8.0.0", - "@vue/eslint-config-typescript": "^12.0.0", - "@vue/tsconfig": "^0.5.1", - "eslint": "^8.49.0", - "eslint-plugin-vue": "^9.17.0", - "npm-run-all2": "^6.1.2", - "prettier": "^3.0.3", - "typescript": "~5.4.0", - "vite": "^5.1.5", - "vue-tsc": "^2.0.6" - } -} diff --git a/pkg/views/partials/header.gohtml b/pkg/views/partials/header.gohtml new file mode 100644 index 0000000..036c18f --- /dev/null +++ b/pkg/views/partials/header.gohtml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + Solarpass + + + diff --git a/pkg/views/public/favicon.png b/pkg/views/public/favicon.png deleted file mode 100644 index 2ca2d07..0000000 Binary files a/pkg/views/public/favicon.png and /dev/null differ diff --git a/pkg/views/signin.gohtml b/pkg/views/signin.gohtml new file mode 100644 index 0000000..3a13c7e --- /dev/null +++ b/pkg/views/signin.gohtml @@ -0,0 +1,34 @@ +
+ + +

{{.i18n.title}}

+

{{.i18n.caption}}

+
+ +
+
+ +
+ + + + + + +
+ {{.i18n.next}} +
+
+
\ No newline at end of file diff --git a/pkg/views/src/assets/utils.css b/pkg/views/src/assets/utils.css deleted file mode 100644 index fd368b0..0000000 --- a/pkg/views/src/assets/utils.css +++ /dev/null @@ -1,14 +0,0 @@ -html, -body, -#app, -.v-application { - font-family: "Roboto Sans", ui-sans-serif, system-ui, sans-serif; -} - -.no-scrollbar { - scrollbar-width: none; -} - -.no-scrollbar::-webkit-scrollbar { - width: 0; -} diff --git a/pkg/views/src/components/Copyright.vue b/pkg/views/src/components/Copyright.vue deleted file mode 100644 index f3f6baa..0000000 --- a/pkg/views/src/components/Copyright.vue +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/pkg/views/src/components/NotificationList.vue b/pkg/views/src/components/NotificationList.vue deleted file mode 100644 index 7f3cfd8..0000000 --- a/pkg/views/src/components/NotificationList.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - diff --git a/pkg/views/src/components/UserMenu.vue b/pkg/views/src/components/UserMenu.vue deleted file mode 100644 index 10a1c28..0000000 --- a/pkg/views/src/components/UserMenu.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/pkg/views/src/components/auth/AccountLocator.vue b/pkg/views/src/components/auth/AccountLocator.vue deleted file mode 100644 index 2a45c90..0000000 --- a/pkg/views/src/components/auth/AccountLocator.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - diff --git a/pkg/views/src/components/auth/CallbackNotify.vue b/pkg/views/src/components/auth/CallbackNotify.vue deleted file mode 100644 index d63c6d6..0000000 --- a/pkg/views/src/components/auth/CallbackNotify.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/pkg/views/src/components/auth/FactorApplicator.vue b/pkg/views/src/components/auth/FactorApplicator.vue deleted file mode 100644 index 8d92c0e..0000000 --- a/pkg/views/src/components/auth/FactorApplicator.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - diff --git a/pkg/views/src/components/auth/FactorPicker.vue b/pkg/views/src/components/auth/FactorPicker.vue deleted file mode 100644 index b107398..0000000 --- a/pkg/views/src/components/auth/FactorPicker.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - diff --git a/pkg/views/src/index.vue b/pkg/views/src/index.vue deleted file mode 100644 index 4f21c35..0000000 --- a/pkg/views/src/index.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/pkg/views/src/layouts/master.vue b/pkg/views/src/layouts/master.vue deleted file mode 100644 index 4b1d5c9..0000000 --- a/pkg/views/src/layouts/master.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/pkg/views/src/layouts/user-center.vue b/pkg/views/src/layouts/user-center.vue deleted file mode 100644 index ddb0690..0000000 --- a/pkg/views/src/layouts/user-center.vue +++ /dev/null @@ -1,22 +0,0 @@ - - \ No newline at end of file diff --git a/pkg/views/src/main.ts b/pkg/views/src/main.ts deleted file mode 100644 index b3665d3..0000000 --- a/pkg/views/src/main.ts +++ /dev/null @@ -1,54 +0,0 @@ -import "virtual:uno.css" - -import "./assets/utils.css" - -import { createApp } from "vue" -import { createPinia } from "pinia" - -import "vuetify/styles" -import { createVuetify } from "vuetify" -import { md3 } from "vuetify/blueprints" -import * as components from "vuetify/components" -import * as labsComponents from "vuetify/labs/components" -import * as directives from "vuetify/directives" - -import "@mdi/font/css/materialdesignicons.min.css" -import "@fontsource/roboto/latin.css" -import "@unocss/reset/tailwind.css" - -import index from "./index.vue" -import router from "./router" - -const app = createApp(index) - -app.use( - createVuetify({ - directives, - components: { - ...components, - ...labsComponents, - }, - blueprint: md3, - theme: { - defaultTheme: "original", - themes: { - original: { - colors: { - primary: "#4a5099", - secondary: "#2196f3", - accent: "#009688", - error: "#f44336", - warning: "#ff9800", - info: "#03a9f4", - success: "#4caf50", - }, - }, - }, - }, - }), -) - -app.use(createPinia()) -app.use(router) - -app.mount("#app") diff --git a/pkg/views/src/router/index.ts b/pkg/views/src/router/index.ts deleted file mode 100644 index e9eea4b..0000000 --- a/pkg/views/src/router/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { createRouter, createWebHistory } from "vue-router" -import { useUserinfo } from "@/stores/userinfo" -import MasterLayout from "@/layouts/master.vue" -import UserCenterLayout from "@/layouts/user-center.vue" - -const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: [ - { - path: "/", - component: MasterLayout, - children: [ - { - path: "/", - component: UserCenterLayout, - children: [ - { - path: "/", - name: "dashboard", - component: () => import("@/views/dashboard.vue"), - meta: { title: "Your account" }, - }, - { - path: "/me/personalize", - name: "personalize", - component: () => import("@/views/personalize.vue"), - meta: { title: "Your personality" }, - }, - { - path: "/me/personal-page", - name: "personal-page", - component: () => import("@/views/personal-page.vue"), - meta: { title: "Your personal page" }, - }, - { - path: "/me/security", - name: "security", - component: () => import("@/views/security.vue"), - meta: { title: "Your security" }, - }, - ], - }, - ], - }, - { - path: "/auth", - children: [ - { - path: "sign-in", - name: "auth.sign-in", - component: () => import("@/views/auth/sign-in.vue"), - meta: { public: true, title: "Sign in" }, - }, - { - path: "sign-up", - name: "auth.sign-up", - component: () => import("@/views/auth/sign-up.vue"), - meta: { public: true, title: "Sign up" }, - }, - { - path: "o/connect", - name: "openid.connect", - component: () => import("@/views/auth/connect.vue"), - }, - - { - path: "/me/confirm", - name: "callback.confirm", - component: () => import("@/views/confirm.vue"), - meta: { public: true, title: "Confirm registration" }, - }, - ], - }, - ], -}) - -router.beforeEach(async (to, from, next) => { - const id = useUserinfo() - if (!id.isReady) { - await id.readProfiles() - } - - if (to.meta.title) { - document.title = `Solarpass | ${to.meta.title}` - } else { - document.title = "Solarpass" - } - - if (!to.meta.public && !id.userinfo.isLoggedIn) { - next({ name: "auth.sign-in", query: { redirect_uri: to.fullPath } }) - } else { - next() - } -}) - -export default router diff --git a/pkg/views/src/scripts/request.ts b/pkg/views/src/scripts/request.ts deleted file mode 100644 index 5540ff2..0000000 --- a/pkg/views/src/scripts/request.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare global { - interface Window { - __LAUNCHPAD_TARGET__?: string - } -} - -export async function request(input: string, init?: RequestInit) { - const prefix = window.__LAUNCHPAD_TARGET__ ?? "" - return await fetch(prefix + input, init) -} diff --git a/pkg/views/src/stores/notifications.ts b/pkg/views/src/stores/notifications.ts deleted file mode 100644 index 974b64c..0000000 --- a/pkg/views/src/stores/notifications.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { defineStore } from "pinia"; -import { ref } from "vue"; -import { checkLoggedIn, getAtk } from "@/stores/userinfo"; -import { request } from "@/scripts/request"; - -export const useNotifications = defineStore("notifications", () => { - let socket: WebSocket; - - const loading = ref(false); - - const notifications = ref([]); - const total = ref(0) - - async function list() { - loading.value = true; - const res = await request( - "/api/notifications?" + - new URLSearchParams({ - take: (25).toString(), - offset: (0).toString() - }), - { - headers: { Authorization: `Bearer ${getAtk()}` } - } - ); - if (res.status === 200) { - const data = await res.json(); - notifications.value = data["data"]; - total.value = data["count"]; - } - loading.value = false; - } - - function remove(idx: number) { - notifications.value.splice(idx, 1) - total.value--; - } - - async function connect() { - if (!(checkLoggedIn())) return; - - const uri = `ws://${window.location.host}/api/notifications/listen`; - - socket = new WebSocket(uri + `?tk=${getAtk() as string}`); - - socket.addEventListener("open", (event) => { - console.log("[NOTIFICATIONS] The listen websocket has been established... ", event.type); - }); - socket.addEventListener("close", (event) => { - console.warn("[NOTIFICATIONS] The listen websocket is disconnected... ", event.reason, event.code); - }); - socket.addEventListener("message", (event) => { - const data = JSON.parse(event.data); - notifications.value.push(data); - total.value++; - }); - } - - function disconnect() { - socket.close(); - } - - return { loading, notifications, total, list, remove, connect, disconnect }; -}); \ No newline at end of file diff --git a/pkg/views/src/stores/userinfo.ts b/pkg/views/src/stores/userinfo.ts deleted file mode 100644 index d58f53c..0000000 --- a/pkg/views/src/stores/userinfo.ts +++ /dev/null @@ -1,54 +0,0 @@ -import Cookie from "universal-cookie" -import { defineStore } from "pinia" -import { ref } from "vue" -import { request } from "@/scripts/request" - -export interface Userinfo { - isLoggedIn: boolean - displayName: string - data: any -} - -const defaultUserinfo: Userinfo = { - isLoggedIn: false, - displayName: "Citizen", - data: null, -} - -export function getAtk(): string { - return new Cookie().get("passport_auth_key") -} - -export function checkLoggedIn(): boolean { - return new Cookie().get("passport_auth_key") -} - -export const useUserinfo = defineStore("userinfo", () => { - const userinfo = ref(defaultUserinfo) - const isReady = ref(false) - - async function readProfiles() { - if (!checkLoggedIn()) { - isReady.value = true - } - - const res = await request("/api/users/me", { - headers: { Authorization: `Bearer ${getAtk()}` }, - }) - - if (res.status !== 200) { - return - } - - const data = await res.json() - - isReady.value = true - userinfo.value = { - isLoggedIn: true, - displayName: data["nick"], - data: data, - } - } - - return { userinfo, isReady, readProfiles } -}) diff --git a/pkg/views/src/views/auth/claims.ts b/pkg/views/src/views/auth/claims.ts deleted file mode 100644 index 6ca79e5..0000000 --- a/pkg/views/src/views/auth/claims.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface ClaimType { - icon: string - name: string - description: string -} - -export const claims: { [id: string]: ClaimType } = { - openid: { - icon: "mdi-identifier", - name: "Open Identity", - description: "Allow them to read your personal information.", - }, -} diff --git a/pkg/views/src/views/auth/connect.vue b/pkg/views/src/views/auth/connect.vue deleted file mode 100644 index e7285e3..0000000 --- a/pkg/views/src/views/auth/connect.vue +++ /dev/null @@ -1,192 +0,0 @@ - - - - - diff --git a/pkg/views/src/views/auth/sign-in.vue b/pkg/views/src/views/auth/sign-in.vue deleted file mode 100644 index dfa9fe8..0000000 --- a/pkg/views/src/views/auth/sign-in.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - diff --git a/pkg/views/src/views/auth/sign-up.vue b/pkg/views/src/views/auth/sign-up.vue deleted file mode 100644 index a206dc3..0000000 --- a/pkg/views/src/views/auth/sign-up.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - diff --git a/pkg/views/src/views/confirm.vue b/pkg/views/src/views/confirm.vue deleted file mode 100644 index c16b984..0000000 --- a/pkg/views/src/views/confirm.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/pkg/views/src/views/dashboard.vue b/pkg/views/src/views/dashboard.vue deleted file mode 100644 index 750e1c4..0000000 --- a/pkg/views/src/views/dashboard.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - diff --git a/pkg/views/src/views/personal-page.vue b/pkg/views/src/views/personal-page.vue deleted file mode 100644 index 782b1df..0000000 --- a/pkg/views/src/views/personal-page.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - diff --git a/pkg/views/src/views/personalize.vue b/pkg/views/src/views/personalize.vue deleted file mode 100644 index 220a185..0000000 --- a/pkg/views/src/views/personalize.vue +++ /dev/null @@ -1,170 +0,0 @@ - - - - - diff --git a/pkg/views/src/views/security.vue b/pkg/views/src/views/security.vue deleted file mode 100644 index 979527f..0000000 --- a/pkg/views/src/views/security.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - - - diff --git a/pkg/views/tsconfig.app.json b/pkg/views/tsconfig.app.json deleted file mode 100644 index e14c754..0000000 --- a/pkg/views/tsconfig.app.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], - "exclude": ["src/**/__tests__/*"], - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - } -} diff --git a/pkg/views/tsconfig.json b/pkg/views/tsconfig.json deleted file mode 100644 index 66b5e57..0000000 --- a/pkg/views/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - } - ] -} diff --git a/pkg/views/tsconfig.node.json b/pkg/views/tsconfig.node.json deleted file mode 100644 index 2c669ee..0000000 --- a/pkg/views/tsconfig.node.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "@tsconfig/node20/tsconfig.json", - "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", "playwright.config.*"], - "compilerOptions": { - "composite": true, - "noEmit": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - - "module": "ESNext", - "moduleResolution": "Bundler", - "types": ["node"] - } -} diff --git a/pkg/views/uno.config.ts b/pkg/views/uno.config.ts deleted file mode 100644 index 2d323f7..0000000 --- a/pkg/views/uno.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { defineConfig, presetAttributify, presetTypography, presetUno } from "unocss" - -export default defineConfig({ - presets: [presetAttributify(), presetTypography(), presetUno({ preflight: false })], -}) diff --git a/pkg/views/vite.config.ts b/pkg/views/vite.config.ts deleted file mode 100644 index e36fe52..0000000 --- a/pkg/views/vite.config.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { fileURLToPath, URL } from "node:url"; - -import { defineConfig } from "vite"; -import vue from "@vitejs/plugin-vue"; -import vueJsx from "@vitejs/plugin-vue-jsx"; -import unocss from "unocss/vite"; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [vue(), vueJsx(), unocss()], - resolve: { - alias: { - "@": fileURLToPath(new URL("./src", import.meta.url)) - } - }, - server: { - proxy: { - "/api/notifications/listen": { - target: "ws://localhost:8444", - ws: true - }, - - "/api": "http://localhost:8444", - "/.well-known": "http://localhost:8444" - } - } -});