119 lines
3.4 KiB
TypeScript
119 lines
3.4 KiB
TypeScript
import { defineStore } from 'pinia';
|
||
import { api } from 'boot/axios';
|
||
import { router } from 'src/router';
|
||
import { IDomainInfo } from '../types/ActionTypes';
|
||
import { jwtDecode } from 'jwt-decode';
|
||
interface UserInfo {
|
||
firstName: string;
|
||
lastName: string;
|
||
email: string;
|
||
}
|
||
|
||
export interface IUserState {
|
||
token?: string;
|
||
returnUrl: string;
|
||
currentDomain: IDomainInfo;
|
||
LeftDrawer: boolean;
|
||
userId?: string;
|
||
userInfo: UserInfo;
|
||
permissions: 'admin' | 'user';
|
||
}
|
||
|
||
export const useAuthStore = defineStore('auth', {
|
||
state: (): IUserState => ({
|
||
token: '',
|
||
returnUrl: '',
|
||
LeftDrawer: false,
|
||
currentDomain: {} as IDomainInfo,
|
||
userId: '',
|
||
userInfo: {} as UserInfo,
|
||
permissions: 'user',
|
||
}),
|
||
getters: {
|
||
toggleLeftDrawer(): boolean {
|
||
return this.LeftDrawer;
|
||
},
|
||
},
|
||
actions: {
|
||
toggleLeftMenu() {
|
||
this.LeftDrawer = !this.LeftDrawer;
|
||
},
|
||
async login(username: string, password: string) {
|
||
const params = new URLSearchParams();
|
||
params.append('username', username);
|
||
params.append('password', password);
|
||
try {
|
||
const result = await api.post(`api/token`, params);
|
||
console.info(result);
|
||
this.token = result.data.access_token;
|
||
const tokenJson = jwtDecode(result.data.access_token);
|
||
this.userId = tokenJson.sub;
|
||
this.permissions = (tokenJson as any).permissions ?? 'user';
|
||
api.defaults.headers['Authorization'] = 'Bearer ' + this.token;
|
||
this.currentDomain = await this.getCurrentDomain();
|
||
this.userInfo = await this.getUserInfo();
|
||
router.push(this.returnUrl || '/');
|
||
return true;
|
||
} catch (e) {
|
||
console.error(e);
|
||
return false;
|
||
}
|
||
},
|
||
async getCurrentDomain(): Promise<IDomainInfo> {
|
||
const activedomain = (await api.get(`api/activedomain`))?.data;
|
||
return {
|
||
id: activedomain?.id,
|
||
domainName: activedomain?.name,
|
||
kintoneUrl: activedomain?.url,
|
||
};
|
||
},
|
||
async getUserDomains(): Promise<IDomainInfo[]> {
|
||
const resp = await api.get(`api/domain`);
|
||
const domains = resp.data as any[];
|
||
return domains.map((data) => ({
|
||
id: data.id,
|
||
domainName: data.name,
|
||
kintoneUrl: data.url,
|
||
}));
|
||
},
|
||
async getUserInfo():Promise<UserInfo>{
|
||
const resp = (await api.get(`api/v1/users/me`)).data;
|
||
return {
|
||
firstName: resp.first_name,
|
||
lastName: resp.last_name,
|
||
email: resp.email,
|
||
}
|
||
},
|
||
logout() {
|
||
this.token = '';
|
||
this.currentDomain = {} as IDomainInfo; // 清空当前域
|
||
router.push('/login');
|
||
},
|
||
async setCurrentDomain(domain: IDomainInfo) {
|
||
if (domain.id === this.currentDomain.id) {
|
||
return;
|
||
}
|
||
await api.put(`api/activedomain/${domain.id}`);
|
||
this.currentDomain = domain;
|
||
},
|
||
},
|
||
persist: {
|
||
afterRestore: (ctx) => {
|
||
api.defaults.headers['Authorization'] = 'Bearer ' + ctx.store.token;
|
||
|
||
//axios例外キャプチャー
|
||
api.interceptors.response.use(
|
||
(response) => response,
|
||
(error) => {
|
||
if (error.response && error.response.status === 401) {
|
||
// 認証エラーの場合再ログインする
|
||
console.error('(; ゚Д゚)/認証エラー(401):', error);
|
||
ctx.store.logout();
|
||
}
|
||
return Promise.reject(error);
|
||
}
|
||
);
|
||
},
|
||
},
|
||
});
|