diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..4a1de47 --- /dev/null +++ b/.env.development @@ -0,0 +1,5 @@ +PUBLIC_LOGTO_CALLBACK_URL=http://localhost:4321/callback +PUBLIC_LOGTO_REDIRECT_URL=http://localhost:4321 +PUBLIC_LOGTO_ENDPOINT=https://auth.app.nbtca.space +PUBLIC_LOGTO_APP_ID=a3tt7oyxeounfiqqugiah +PUBLIC_SITE_URL=http://localhost:4321 diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..2904758 --- /dev/null +++ b/.env.production @@ -0,0 +1,6 @@ +PUBLIC_LOGTO_CALLBACK_URL=https://nbtca.space/callback +PUBLIC_LOGTO_REDIRECT_URL=https://nbtca.space +PUBLIC_LOGTO_ENDPOINT=https://auth.app.nbtca.space +PUBLIC_LOGTO_APP_ID=a3tt7oyxeounfiqqugiah +PUBLIC_LOGTO_RESOURCE=https://api.nbtca.space +PUBLIC_SITE_URL=https://nbtca.space \ No newline at end of file diff --git a/.gitignore b/.gitignore index ed05d61..6e52ada 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,8 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* - -# environment variables -.env -.env.production +.env.local +.env.*.local # macOS-specific files .DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json index de14803..b0d60c1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ ], "eslint.experimental.useFlatConfig": true, "cSpell.words": [ + "Logto", "qrcode" ], } diff --git a/cspell.json b/cspell.json index 475da53..60d602b 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,9 @@ "astro", "astrojs", "frontmatter", + "logto", + "logtoClient", + "Logto", "m_lfit", "N3ptune", "NBTCA", diff --git a/package.json b/package.json index 9c3a0a5..2a75b23 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "@fullcalendar/daygrid": "^6.1.11", "@fullcalendar/icalendar": "^6.1.11", "@fullcalendar/react": "^6.1.11", + "@headlessui/vue": "^1.7.22", + "@logto/browser": "^2.2.16", "@stylistic/eslint-plugin": "^2.1.0", "astro": "^4.5.12", "ical.js": "^1.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb2bb2b..052f8dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,12 @@ dependencies: '@fullcalendar/react': specifier: ^6.1.11 version: 6.1.14(@fullcalendar/core@6.1.14)(react-dom@18.3.1)(react@18.3.1) + '@headlessui/vue': + specifier: ^1.7.22 + version: 1.7.22(vue@3.4.31) + '@logto/browser': + specifier: ^2.2.16 + version: 2.2.16 '@stylistic/eslint-plugin': specifier: ^2.1.0 version: 2.3.0(eslint@8.57.0)(typescript@5.5.3) @@ -1258,6 +1264,16 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@headlessui/vue@1.7.22(vue@3.4.31): + resolution: {integrity: sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==} + engines: {node: '>=10'} + peerDependencies: + vue: ^3.2.0 + dependencies: + '@tanstack/vue-virtual': 3.10.4(vue@3.4.31) + vue: 3.4.31(typescript@5.5.3) + dev: false + /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -1506,6 +1522,30 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /@logto/browser@2.2.16: + resolution: {integrity: sha512-kGodGK8VE3vnbF1PuDronc3YW5PxG9ksQRQJO4FWizCQDStnaYhT8w+ftlhyrZSoyre6hwtuc3fOj2tE+J5e2A==} + dependencies: + '@logto/client': 2.7.3 + '@silverhand/essentials': 2.9.1 + js-base64: 3.7.7 + dev: false + + /@logto/client@2.7.3: + resolution: {integrity: sha512-slHm+fPU1vwfKDUNmKmsBHZhWv6pH1DW0p87axy2PEy6/B3aKKQRpW1J/6AhR3JyYfcElmykFGlvr5yT1HZGYQ==} + dependencies: + '@logto/js': 4.1.5 + '@silverhand/essentials': 2.9.1 + camelcase-keys: 7.0.2 + jose: 5.7.0 + dev: false + + /@logto/js@4.1.5: + resolution: {integrity: sha512-3TpF2WKsjFyt0Gqc4gYV3zGbfDp+2cI6Tp2lGvptCfOn6K4sUccjve3jU7IKih1aACS5CdvlEybg5B7rvcbvpg==} + dependencies: + '@silverhand/essentials': 2.9.1 + camelcase-keys: 7.0.2 + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1719,6 +1759,11 @@ packages: resolution: {integrity: sha512-qdiJS5a/QGCff7VUFIqd0hDdWly9rDp8lhVmXVrS11aazX8LOTRLHAXkkEeONNsS43EcCd7gax9LLoOz4vlFQA==} dev: false + /@silverhand/essentials@2.9.1: + resolution: {integrity: sha512-rsql/ZxXMqVvt7ySDHd7xjCog4oCYg+dexxlj3veolajwjKiy/08ZtFyEtFjSEAaKbXwkWZ4TDtiNSxb7HS0yA==} + engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^9.0.0} + dev: false + /@stylistic/eslint-plugin-js@2.3.0(eslint@8.57.0): resolution: {integrity: sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1790,6 +1835,19 @@ packages: - typescript dev: false + /@tanstack/virtual-core@3.10.4: + resolution: {integrity: sha512-yHyli4RHVsI+eJ0RjmOsjA9RpHp3/Zah9t+iRjmFa72dq00TeG/NwuLYuCV6CB4RkWD4i5RD421j1eb6BdKgvQ==} + dev: false + + /@tanstack/vue-virtual@3.10.4(vue@3.4.31): + resolution: {integrity: sha512-oikrjnC7BnUCmqh5ptemclUK6EtJj48AdLcJx1t2fTLQyu+60Alo6gPGC3cANgmbEP/1C9DptbeMcm5AAjyBVg==} + peerDependencies: + vue: ^2.7.0 || ^3.0.0 + dependencies: + '@tanstack/virtual-core': 3.10.4 + vue: 3.4.31(typescript@5.5.3) + dev: false + /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: @@ -2637,6 +2695,16 @@ packages: engines: {node: '>= 6'} dev: false + /camelcase-keys@7.0.2: + resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} + engines: {node: '>=12'} + dependencies: + camelcase: 6.3.0 + map-obj: 4.3.0 + quick-lru: 5.1.1 + type-fest: 1.4.0 + dev: false + /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -4366,6 +4434,14 @@ packages: hasBin: true dev: false + /jose@5.7.0: + resolution: {integrity: sha512-3P9qfTYDVnNn642LCAqIKbTGb9a1TBxZ9ti5zEVEr48aDdflgRjhspWFb6WM4PzAfFbGMJYC4+803v8riCRAKw==} + dev: false + + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + dev: false + /js-levenshtein@1.1.6: resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} engines: {node: '>=0.10.0'} @@ -4580,6 +4656,11 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: false + /markdown-table@3.0.3: resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} dev: false @@ -5628,6 +5709,11 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + /react-dom@18.3.1(react@18.3.1): resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -6361,6 +6447,11 @@ packages: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + /type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: false + /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro index 1a35770..8d2a826 100644 --- a/src/components/Navigation.astro +++ b/src/components/Navigation.astro @@ -1,6 +1,7 @@ --- import { SITE_TITLE } from "../consts" import { ref } from "vue" +import NavigationUser from "./NavigationUser.vue" const menuList = ref<{ link: string @@ -10,10 +11,10 @@ const menuList = ref<{ link: "/archive", name: "目录", }, - { - link: "https://repair.nbtca.space", - name: "维修", - }, + // { + // link: "https://repair.nbtca.space", + // name: "维修", + // }, { link: "/calendar", name: "日历", @@ -50,6 +51,7 @@ const menuList = ref<{ ), ) } + diff --git a/src/components/NavigationUser.vue b/src/components/NavigationUser.vue new file mode 100644 index 0000000..c3f2e62 --- /dev/null +++ b/src/components/NavigationUser.vue @@ -0,0 +1,73 @@ + + diff --git a/src/consts.ts b/src/consts.ts index c777290..04709de 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -2,4 +2,4 @@ export const SITE_TITLE = `拔电关机` export const SITE_EMAIL = "contact@nbtca.space" export const SITE_NAME = "Computer Association" export const SITE_DESCRIPTION = "Computer Association" -export const SITE_URL = "https://www.nbtca.space" +export const SITE_URL = import.meta.env.PUBLIC_SITE_URL diff --git a/src/env.d.ts b/src/env.d.ts index acef35f..030dc9b 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,2 +1,11 @@ -/// -/// +interface ImportMetaEnv { + readonly PUBLIC_SITE_URL: string + readonly PUBLIC_LOGTO_CALLBACK_URL: string + readonly PUBLIC_LOGTO_REDIRECT_URL: string + readonly PUBLIC_LOGTO_APP_ID: string + readonly PUBLIC_LOGTO_ENDPOINT: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} diff --git a/src/pages/callback.astro b/src/pages/callback.astro new file mode 100644 index 0000000..ae40e4e --- /dev/null +++ b/src/pages/callback.astro @@ -0,0 +1,23 @@ +
+ + diff --git a/src/styles/global.css b/src/styles/global.css index 00970d9..68e7733 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -101,7 +101,7 @@ progress { button { background: none; border: 0; - box-sizing: content-box; + box-sizing: border-box; color: inherit; cursor: pointer; font: inherit; diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 0000000..f236c05 --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,6 @@ +import LogtoClient from "@logto/browser" + +export const logtoClient = new LogtoClient({ + endpoint: import.meta.env.PUBLIC_LOGTO_ENDPOINT, + appId: import.meta.env.PUBLIC_LOGTO_APP_ID, +})