mirror of https://github.com/halo-dev/halo
parent
9dc7016f06
commit
9765dd5529
|
@ -34,6 +34,7 @@
|
||||||
"floating-vue": "2.0.0-beta.16",
|
"floating-vue": "2.0.0-beta.16",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"pinia": "^2.0.14",
|
"pinia": "^2.0.14",
|
||||||
|
"qs": "^6.11.0",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
"vue-filepond": "^7.0.3",
|
"vue-filepond": "^7.0.3",
|
||||||
|
@ -46,6 +47,8 @@
|
||||||
"@types/jsdom": "^16.2.14",
|
"@types/jsdom": "^16.2.14",
|
||||||
"@types/lodash.clonedeep": "4.5.7",
|
"@types/lodash.clonedeep": "4.5.7",
|
||||||
"@types/node": "^17.0.45",
|
"@types/node": "^17.0.45",
|
||||||
|
"@types/qs": "^6.9.7",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
"@vitejs/plugin-vue": "^2.3.3",
|
"@vitejs/plugin-vue": "^2.3.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||||
"@vitest/ui": "^0.15.2",
|
"@vitest/ui": "^0.15.2",
|
||||||
|
|
|
@ -5,4 +5,17 @@ const axiosInstance = axios.create({
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
axiosInstance.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
async (error) => {
|
||||||
|
console.log("error", error);
|
||||||
|
if (error.response.status === 401) {
|
||||||
|
window.location.href = "/#/login";
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export { axiosInstance };
|
export { axiosInstance };
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
const { themeable } = require("tailwindcss-themeable");
|
const { themeable } = require("tailwindcss-themeable");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
|
content: ["./src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require("tailwindcss-safe-area"),
|
require("tailwindcss-safe-area"),
|
||||||
require("@tailwindcss/aspect-ratio"),
|
|
||||||
themeable({
|
themeable({
|
||||||
defaultTheme: "default",
|
defaultTheme: "default",
|
||||||
themes: [
|
themes: [
|
||||||
|
|
|
@ -12,6 +12,8 @@ importers:
|
||||||
'@types/jsdom': ^16.2.14
|
'@types/jsdom': ^16.2.14
|
||||||
'@types/lodash.clonedeep': 4.5.7
|
'@types/lodash.clonedeep': 4.5.7
|
||||||
'@types/node': ^17.0.45
|
'@types/node': ^17.0.45
|
||||||
|
'@types/qs': ^6.9.7
|
||||||
|
'@types/uuid': ^8.3.4
|
||||||
'@vitejs/plugin-vue': ^2.3.3
|
'@vitejs/plugin-vue': ^2.3.3
|
||||||
'@vitejs/plugin-vue-jsx': ^1.3.10
|
'@vitejs/plugin-vue-jsx': ^1.3.10
|
||||||
'@vitest/ui': ^0.15.2
|
'@vitest/ui': ^0.15.2
|
||||||
|
@ -36,6 +38,7 @@ importers:
|
||||||
postcss: ^8.4.14
|
postcss: ^8.4.14
|
||||||
prettier: ^2.7.1
|
prettier: ^2.7.1
|
||||||
prettier-plugin-tailwindcss: ^0.1.11
|
prettier-plugin-tailwindcss: ^0.1.11
|
||||||
|
qs: ^6.11.0
|
||||||
sass: ^1.53.0
|
sass: ^1.53.0
|
||||||
start-server-and-test: ^1.14.0
|
start-server-and-test: ^1.14.0
|
||||||
tailwindcss: ^3.1.4
|
tailwindcss: ^3.1.4
|
||||||
|
@ -65,6 +68,7 @@ importers:
|
||||||
floating-vue: 2.0.0-beta.16_vue@3.2.37
|
floating-vue: 2.0.0-beta.16_vue@3.2.37
|
||||||
lodash.clonedeep: 4.5.0
|
lodash.clonedeep: 4.5.0
|
||||||
pinia: 2.0.14_j6bzmzd4ujpabbp5objtwxyjp4
|
pinia: 2.0.14_j6bzmzd4ujpabbp5objtwxyjp4
|
||||||
|
qs: 6.11.0
|
||||||
uuid: 8.3.2
|
uuid: 8.3.2
|
||||||
vue: 3.2.37
|
vue: 3.2.37
|
||||||
vue-filepond: 7.0.3_filepond@4.30.4+vue@3.2.37
|
vue-filepond: 7.0.3_filepond@4.30.4+vue@3.2.37
|
||||||
|
@ -76,6 +80,8 @@ importers:
|
||||||
'@types/jsdom': 16.2.14
|
'@types/jsdom': 16.2.14
|
||||||
'@types/lodash.clonedeep': 4.5.7
|
'@types/lodash.clonedeep': 4.5.7
|
||||||
'@types/node': 17.0.45
|
'@types/node': 17.0.45
|
||||||
|
'@types/qs': 6.9.7
|
||||||
|
'@types/uuid': 8.3.4
|
||||||
'@vitejs/plugin-vue': 2.3.3_vite@2.9.12+vue@3.2.37
|
'@vitejs/plugin-vue': 2.3.3_vite@2.9.12+vue@3.2.37
|
||||||
'@vitejs/plugin-vue-jsx': 1.3.10
|
'@vitejs/plugin-vue-jsx': 1.3.10
|
||||||
'@vitest/ui': 0.15.2
|
'@vitest/ui': 0.15.2
|
||||||
|
@ -1472,7 +1478,7 @@ packages:
|
||||||
axios: 0.24.0
|
axios: 0.24.0
|
||||||
form-data: 4.0.0
|
form-data: 4.0.0
|
||||||
js-base64: 3.7.2
|
js-base64: 3.7.2
|
||||||
qs: 6.10.3
|
qs: 6.11.0
|
||||||
tslib: 2.4.0
|
tslib: 2.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
|
@ -2156,6 +2162,10 @@ packages:
|
||||||
resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
|
resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/uuid/8.3.4:
|
||||||
|
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/web-bluetooth/0.0.14:
|
/@types/web-bluetooth/0.0.14:
|
||||||
resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==}
|
resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==}
|
||||||
|
|
||||||
|
@ -5763,6 +5773,14 @@ packages:
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel: 1.0.4
|
side-channel: 1.0.4
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/qs/6.11.0:
|
||||||
|
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
|
||||||
|
engines: {node: '>=0.6'}
|
||||||
|
dependencies:
|
||||||
|
side-channel: 1.0.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
/qs/6.5.3:
|
/qs/6.5.3:
|
||||||
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { VButton, VInput, VSpace } from "@halo-dev/components";
|
||||||
|
import { v4 as uuid } from "uuid";
|
||||||
|
import { axiosInstance } from "@halo-dev/admin-shared";
|
||||||
|
import qs from "qs";
|
||||||
|
import logo from "../../../assets/logo.svg";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
interface LoginForm {
|
||||||
|
_csrf: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoginFormState {
|
||||||
|
logging: boolean;
|
||||||
|
state: LoginForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const loginForm = ref<LoginFormState>({
|
||||||
|
logging: false,
|
||||||
|
state: {
|
||||||
|
_csrf: "",
|
||||||
|
username: "admin",
|
||||||
|
password: "wsYdVrLTYnLbzN6e",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleGenerateToken = async () => {
|
||||||
|
const token = uuid();
|
||||||
|
loginForm.value.state._csrf = token;
|
||||||
|
document.cookie = `XSRF-TOKEN=${token}; Path=/;`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogin = async () => {
|
||||||
|
try {
|
||||||
|
loginForm.value.logging = true;
|
||||||
|
|
||||||
|
await axiosInstance.post(
|
||||||
|
`http://localhost:8090/login`,
|
||||||
|
qs.stringify(loginForm.value.state),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
await router.replace({ name: "Dashboard" });
|
||||||
|
loginForm.value.logging = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
handleGenerateToken();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="flex h-screen flex-col items-center justify-center">
|
||||||
|
<img :src="logo" alt="Logo" class="mb-8 w-20" />
|
||||||
|
<div class="login-form w-72">
|
||||||
|
<VSpace class="w-full" direction="column" spacing="lg">
|
||||||
|
<VInput
|
||||||
|
v-model="loginForm.state.username"
|
||||||
|
placeholder="用户名"
|
||||||
|
></VInput>
|
||||||
|
<VInput v-model="loginForm.state.password" placeholder="密码"></VInput>
|
||||||
|
<VButton block type="secondary" @click="handleLogin">登录</VButton>
|
||||||
|
</VSpace>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -9,12 +9,18 @@ import UserDetail from "./UserDetail.vue";
|
||||||
import ProfileModification from "./ProfileModification.vue";
|
import ProfileModification from "./ProfileModification.vue";
|
||||||
import PasswordChange from "./PasswordChange.vue";
|
import PasswordChange from "./PasswordChange.vue";
|
||||||
import PersonalAccessTokens from "./PersonalAccessTokens.vue";
|
import PersonalAccessTokens from "./PersonalAccessTokens.vue";
|
||||||
|
import Login from "./Login.vue";
|
||||||
import { IconUserSettings } from "@halo-dev/components";
|
import { IconUserSettings } from "@halo-dev/components";
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "userModule",
|
name: "userModule",
|
||||||
components: [],
|
components: [],
|
||||||
routes: [
|
routes: [
|
||||||
|
{
|
||||||
|
path: "/login",
|
||||||
|
name: "Login",
|
||||||
|
component: Login,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/users",
|
path: "/users",
|
||||||
component: BlankLayout,
|
component: BlankLayout,
|
||||||
|
|
Loading…
Reference in New Issue