mirror of
https://github.com/m1ngsama/FUJI.git
synced 2025-12-24 10:51:27 +00:00
add auth
This commit is contained in:
parent
aa39717a07
commit
a29e54b0e9
14 changed files with 231 additions and 12 deletions
5
.env.development
Normal file
5
.env.development
Normal file
|
|
@ -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
|
||||||
6
.env.production
Normal file
6
.env.production
Normal file
|
|
@ -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
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -11,10 +11,8 @@ yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
.env.local
|
||||||
# environment variables
|
.env.*.local
|
||||||
.env
|
|
||||||
.env.production
|
|
||||||
|
|
||||||
# macOS-specific files
|
# macOS-specific files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -8,6 +8,7 @@
|
||||||
],
|
],
|
||||||
"eslint.experimental.useFlatConfig": true,
|
"eslint.experimental.useFlatConfig": true,
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"Logto",
|
||||||
"qrcode"
|
"qrcode"
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
"astro",
|
"astro",
|
||||||
"astrojs",
|
"astrojs",
|
||||||
"frontmatter",
|
"frontmatter",
|
||||||
|
"logto",
|
||||||
|
"logtoClient",
|
||||||
|
"Logto",
|
||||||
"m_lfit",
|
"m_lfit",
|
||||||
"N3ptune",
|
"N3ptune",
|
||||||
"NBTCA",
|
"NBTCA",
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
"@fullcalendar/daygrid": "^6.1.11",
|
"@fullcalendar/daygrid": "^6.1.11",
|
||||||
"@fullcalendar/icalendar": "^6.1.11",
|
"@fullcalendar/icalendar": "^6.1.11",
|
||||||
"@fullcalendar/react": "^6.1.11",
|
"@fullcalendar/react": "^6.1.11",
|
||||||
|
"@headlessui/vue": "^1.7.22",
|
||||||
|
"@logto/browser": "^2.2.16",
|
||||||
"@stylistic/eslint-plugin": "^2.1.0",
|
"@stylistic/eslint-plugin": "^2.1.0",
|
||||||
"astro": "^4.5.12",
|
"astro": "^4.5.12",
|
||||||
"ical.js": "^1.5.0",
|
"ical.js": "^1.5.0",
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,12 @@ dependencies:
|
||||||
'@fullcalendar/react':
|
'@fullcalendar/react':
|
||||||
specifier: ^6.1.11
|
specifier: ^6.1.11
|
||||||
version: 6.1.14(@fullcalendar/core@6.1.14)(react-dom@18.3.1)(react@18.3.1)
|
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':
|
'@stylistic/eslint-plugin':
|
||||||
specifier: ^2.1.0
|
specifier: ^2.1.0
|
||||||
version: 2.3.0(eslint@8.57.0)(typescript@5.5.3)
|
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)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
dev: false
|
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:
|
/@humanwhocodes/config-array@0.11.14:
|
||||||
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
||||||
engines: {node: '>=10.10.0'}
|
engines: {node: '>=10.10.0'}
|
||||||
|
|
@ -1506,6 +1522,30 @@ packages:
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
dev: false
|
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:
|
/@nodelib/fs.scandir@2.1.5:
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
@ -1719,6 +1759,11 @@ packages:
|
||||||
resolution: {integrity: sha512-qdiJS5a/QGCff7VUFIqd0hDdWly9rDp8lhVmXVrS11aazX8LOTRLHAXkkEeONNsS43EcCd7gax9LLoOz4vlFQA==}
|
resolution: {integrity: sha512-qdiJS5a/QGCff7VUFIqd0hDdWly9rDp8lhVmXVrS11aazX8LOTRLHAXkkEeONNsS43EcCd7gax9LLoOz4vlFQA==}
|
||||||
dev: false
|
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):
|
/@stylistic/eslint-plugin-js@2.3.0(eslint@8.57.0):
|
||||||
resolution: {integrity: sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==}
|
resolution: {integrity: sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
@ -1790,6 +1835,19 @@ packages:
|
||||||
- typescript
|
- typescript
|
||||||
dev: false
|
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:
|
/@types/babel__core@7.20.5:
|
||||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -2637,6 +2695,16 @@ packages:
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dev: false
|
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:
|
/camelcase@5.3.1:
|
||||||
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
@ -4366,6 +4434,14 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
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:
|
/js-levenshtein@1.1.6:
|
||||||
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
@ -4580,6 +4656,11 @@ packages:
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/map-obj@4.3.0:
|
||||||
|
resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/markdown-table@3.0.3:
|
/markdown-table@3.0.3:
|
||||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -5628,6 +5709,11 @@ packages:
|
||||||
/queue-microtask@1.2.3:
|
/queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
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):
|
/react-dom@18.3.1(react@18.3.1):
|
||||||
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
|
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -6361,6 +6447,11 @@ packages:
|
||||||
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
||||||
engines: {node: '>=10'}
|
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:
|
/type-fest@2.19.0:
|
||||||
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import { SITE_TITLE } from "../consts"
|
import { SITE_TITLE } from "../consts"
|
||||||
import { ref } from "vue"
|
import { ref } from "vue"
|
||||||
|
import NavigationUser from "./NavigationUser.vue"
|
||||||
|
|
||||||
const menuList = ref<{
|
const menuList = ref<{
|
||||||
link: string
|
link: string
|
||||||
|
|
@ -10,10 +11,10 @@ const menuList = ref<{
|
||||||
link: "/archive",
|
link: "/archive",
|
||||||
name: "目录",
|
name: "目录",
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
link: "https://repair.nbtca.space",
|
// link: "https://repair.nbtca.space",
|
||||||
name: "维修",
|
// name: "维修",
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
link: "/calendar",
|
link: "/calendar",
|
||||||
name: "日历",
|
name: "日历",
|
||||||
|
|
@ -50,6 +51,7 @@ const menuList = ref<{
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
<NavigationUser client:load />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
73
src/components/NavigationUser.vue
Normal file
73
src/components/NavigationUser.vue
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from "vue"
|
||||||
|
import { logtoClient } from "../utils/auth"
|
||||||
|
import type { IdTokenClaims } from "@logto/browser"
|
||||||
|
import { Menu, MenuButton, MenuItems, MenuItem } from "@headlessui/vue"
|
||||||
|
|
||||||
|
const onSignIn = async () => {
|
||||||
|
logtoClient.signIn(import.meta.env.PUBLIC_LOGTO_CALLBACK_URL)
|
||||||
|
}
|
||||||
|
const onSignOut = async () => {
|
||||||
|
logtoClient.signOut(import.meta.env.PUBLIC_LOGTO_REDIRECT_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAuthenticated = ref<boolean>()
|
||||||
|
const userInfo = ref<IdTokenClaims>()
|
||||||
|
const initAuth = async () => {
|
||||||
|
try {
|
||||||
|
await Promise.all([
|
||||||
|
userInfo.value = await logtoClient.getIdTokenClaims(),
|
||||||
|
isAuthenticated.value = await logtoClient.isAuthenticated()
|
||||||
|
])
|
||||||
|
} catch (error) {
|
||||||
|
isAuthenticated.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
initAuth()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-center w-12">
|
||||||
|
<div @click="onSignIn" v-if="isAuthenticated === false" class="">
|
||||||
|
<a class="nav-item-content px-2 hover:text-[#2997ff] text-nowrap cursor-pointer">登入</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center" v-if="isAuthenticated">
|
||||||
|
<Menu as="div" class="relative inline-block text-left">
|
||||||
|
<div>
|
||||||
|
<MenuButton class="flex items-center focus:outline-none">
|
||||||
|
<div class="h-7 w-7 rounded-full border border-gray-300 overflow-hidden">
|
||||||
|
<img :src="userInfo.picture" alt="" class="w-full" />
|
||||||
|
</div>
|
||||||
|
</MenuButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<transition
|
||||||
|
enter-active-class="transition duration-100 ease-out"
|
||||||
|
enter-from-class="transform scale-95 opacity-0"
|
||||||
|
enter-to-class="transform scale-100 opacity-100"
|
||||||
|
leave-active-class="transition duration-75 ease-in"
|
||||||
|
leave-from-class="transform scale-100 opacity-100"
|
||||||
|
leave-to-class="transform scale-95 opacity-0"
|
||||||
|
>
|
||||||
|
<MenuItems
|
||||||
|
class="absolute right-0 mt-2 w-32 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none"
|
||||||
|
>
|
||||||
|
<div class="px-1 py-1">
|
||||||
|
<MenuItem v-slot="{ active }">
|
||||||
|
<button
|
||||||
|
@click="onSignOut"
|
||||||
|
:class="[active ? 'bg-violet-500 text-white' : 'text-gray-900', 'flex w-full items-center rounded-md px-2 py-2 text-sm']"
|
||||||
|
>
|
||||||
|
登出
|
||||||
|
</button>
|
||||||
|
</MenuItem>
|
||||||
|
</div>
|
||||||
|
</MenuItems>
|
||||||
|
</transition>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div v-if="isAuthenticated" @click="onSignOut" class="px-2">Sign-Out</div> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -2,4 +2,4 @@ export const SITE_TITLE = `拔电关机`
|
||||||
export const SITE_EMAIL = "contact@nbtca.space"
|
export const SITE_EMAIL = "contact@nbtca.space"
|
||||||
export const SITE_NAME = "Computer Association"
|
export const SITE_NAME = "Computer Association"
|
||||||
export const SITE_DESCRIPTION = "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
|
||||||
|
|
|
||||||
13
src/env.d.ts
vendored
13
src/env.d.ts
vendored
|
|
@ -1,2 +1,11 @@
|
||||||
/// <reference path="../.astro/types.d.ts" />
|
interface ImportMetaEnv {
|
||||||
/// <reference types="astro/client" />
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
23
src/pages/callback.astro
Normal file
23
src/pages/callback.astro
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { logtoClient } from "../utils/auth"
|
||||||
|
import LogtoClient from "@logto/browser"
|
||||||
|
|
||||||
|
const callbackHandler = async (logtoClient: LogtoClient) => {
|
||||||
|
try {
|
||||||
|
await logtoClient.handleSignInCallback(window.location.href)
|
||||||
|
if (!logtoClient.isAuthenticated) {
|
||||||
|
window.location.assign("/")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Handle successful sign-in
|
||||||
|
window.location.assign("/")
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
window.location.assign("/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callbackHandler(logtoClient)
|
||||||
|
</script>
|
||||||
|
|
@ -101,7 +101,7 @@ progress {
|
||||||
button {
|
button {
|
||||||
background: none;
|
background: none;
|
||||||
border: 0;
|
border: 0;
|
||||||
box-sizing: content-box;
|
box-sizing: border-box;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
|
|
|
||||||
6
src/utils/auth.ts
Normal file
6
src/utils/auth.ts
Normal file
|
|
@ -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,
|
||||||
|
})
|
||||||
Loading…
Reference in a new issue