UserDomain Add
This commit is contained in:
@@ -138,3 +138,49 @@ async def flow_delete(
|
||||
):
|
||||
|
||||
return delete_flow(db, flowid)
|
||||
|
||||
@r.get(
|
||||
"/domain/{userid}",
|
||||
response_model=List[Domain],
|
||||
response_model_exclude_none=True,
|
||||
)
|
||||
async def domain_details(
|
||||
request: Request,
|
||||
userid: str,
|
||||
db=Depends(get_db),
|
||||
):
|
||||
domains = get_domain(db, userid)
|
||||
return domains
|
||||
|
||||
|
||||
@r.post("/domain", response_model=Domain, response_model_exclude_none=True)
|
||||
async def domain_create(
|
||||
request: Request,
|
||||
domain: DomainBase,
|
||||
db=Depends(get_db),
|
||||
):
|
||||
return create_domain(db, domain)
|
||||
|
||||
|
||||
@r.put(
|
||||
"/domain", response_model=Domain, response_model_exclude_none=True
|
||||
)
|
||||
async def domain_edit(
|
||||
request: Request,
|
||||
domain: DomainBase,
|
||||
db=Depends(get_db),
|
||||
):
|
||||
return edit_domain(db, domain)
|
||||
|
||||
|
||||
@r.delete(
|
||||
"/domain/{userid}/{id}", response_model=Domain, response_model_exclude_none=True
|
||||
)
|
||||
async def domain_delete(
|
||||
request: Request,
|
||||
userid: int,
|
||||
id: int,
|
||||
db=Depends(get_db),
|
||||
):
|
||||
|
||||
return delete_domain(db, userid,id)
|
||||
@@ -180,3 +180,48 @@ def get_flows_by_app(db: Session, appid: str):
|
||||
if not flows:
|
||||
raise HTTPException(status_code=404, detail="Data not found")
|
||||
return flows
|
||||
|
||||
def create_domain(db: Session, domain: schemas.DomainBase):
|
||||
db_domain = models.UserDomain(
|
||||
userid=domain.userid,
|
||||
name=domain.name,
|
||||
url=domain.url,
|
||||
kintoneuser=domain.kintoneuser,
|
||||
kintonepwd=domain.kintonepwd
|
||||
)
|
||||
db.add(db_domain)
|
||||
db.commit()
|
||||
db.refresh(db_domain)
|
||||
return db_domain
|
||||
|
||||
def delete_domain(db: Session, userid: int,id: int):
|
||||
db_domain = db.query(models.UserDomain).get(id)
|
||||
if not db_domain or db_domain.userid != userid:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Domain not found")
|
||||
db.delete(db_domain)
|
||||
db.commit()
|
||||
return db_domain
|
||||
|
||||
|
||||
def edit_domain(
|
||||
db: Session, domain: schemas.DomainBase
|
||||
) -> schemas.Domain:
|
||||
db_domain = db.query(models.UserDomain).get(domain.id)
|
||||
if not db_domain or db_domain.userid != domain.userid:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Domain not found")
|
||||
update_data = domain.dict(exclude_unset=True)
|
||||
|
||||
for key, value in update_data.items():
|
||||
if(key != "id"):
|
||||
setattr(db_domain, key, value)
|
||||
|
||||
db.add(db_domain)
|
||||
db.commit()
|
||||
db.refresh(db_domain)
|
||||
return db_domain
|
||||
|
||||
def get_domain(db: Session, userid: str):
|
||||
domains = db.query(models.UserDomain).filter(models.UserDomain.userid == userid).all()
|
||||
if not domains:
|
||||
raise HTTPException(status_code=404, detail="Data not found")
|
||||
return domains
|
||||
@@ -1,4 +1,4 @@
|
||||
from sqlalchemy import Boolean, Column, Integer, String, DateTime
|
||||
from sqlalchemy import Boolean, Column, Integer, String, DateTime,ForeignKey
|
||||
from sqlalchemy.ext.declarative import as_declarative
|
||||
from datetime import datetime
|
||||
|
||||
@@ -49,3 +49,13 @@ class Flow(Base):
|
||||
eventid = Column(String(100), index=True, nullable=False)
|
||||
name = Column(String(200))
|
||||
content = Column(String)
|
||||
|
||||
class UserDomain(Base):
|
||||
__tablename__ = "userdomain"
|
||||
|
||||
userid = Column(Integer,ForeignKey("user.id"))
|
||||
name = Column(String(100), nullable=False)
|
||||
url = Column(String(200), nullable=False)
|
||||
kintoneuser = Column(String(100), nullable=False)
|
||||
kintonepwd = Column(String(100), nullable=False)
|
||||
active = Column(Boolean, default=False)
|
||||
@@ -103,3 +103,24 @@ class Flow(Base):
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
class DomainBase(BaseModel):
|
||||
id: int
|
||||
userid: int
|
||||
name: str
|
||||
url: str
|
||||
kintoneuser: str
|
||||
kintonepwd: str
|
||||
active:bool = False
|
||||
|
||||
class Domain(Base):
|
||||
id: int
|
||||
userid: str
|
||||
name: str
|
||||
url: str
|
||||
kintoneuser: str
|
||||
kintonepwd: str
|
||||
active:bool
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
21
frontend/src/control/auth.ts
Normal file
21
frontend/src/control/auth.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { api } from 'boot/axios';
|
||||
|
||||
export class Auth
|
||||
{
|
||||
async login(user:string,pwd:string):Promise<boolean>
|
||||
{
|
||||
const params = new URLSearchParams();
|
||||
params.append('username', user);
|
||||
params.append('password', pwd);
|
||||
try{
|
||||
const result = await api.post(`http://127.0.0.1:8000/api/token`,params);
|
||||
console.info(result);
|
||||
localStorage.setItem('Token', result.data.access_token);
|
||||
return true;
|
||||
}catch(e)
|
||||
{
|
||||
console.info(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,9 @@
|
||||
Kintone App Builder
|
||||
<q-badge align="top" outline>V{{ env.version }}</q-badge>
|
||||
</q-toolbar-title>
|
||||
<q-btn flat round dense icon="logout" @click="authStore.logout()"/>
|
||||
</q-toolbar>
|
||||
|
||||
</q-header>
|
||||
|
||||
<q-drawer
|
||||
@@ -46,6 +48,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue';
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const essentialLinks: EssentialLinkProps[] = [
|
||||
{
|
||||
|
||||
100
frontend/src/pages/LoginPage.vue
Normal file
100
frontend/src/pages/LoginPage.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<q-layout view="lHh Lpr fff">
|
||||
<q-page-container>
|
||||
<q-page class="window-height window-width row justify-center items-center">
|
||||
<div class="column q-pa-lg">
|
||||
<div class="row">
|
||||
<q-card square class="shadow-24" style="width:400px;height:540px;">
|
||||
<q-card-section class="bg-primary">
|
||||
<h4 class="text-h5 text-white q-my-md">{{ title}}</h4>
|
||||
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form class="q-px-sm q-pt-xl" ref="loginForm">
|
||||
<q-input square clearable v-model="email" type="email" lazy-rules
|
||||
:rules="[required,isEmail,short]" label="メール">
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="email" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input square clearable v-model="password" :type="passwordFieldType" lazy-rules
|
||||
:rules="[required, short]" label="パスワード">
|
||||
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="lock" />
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-icon :name="visibilityIcon" @click="switchVisibility" class="cursor-pointer" />
|
||||
</template>
|
||||
</q-input>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions class="q-px-lg">
|
||||
<q-btn unelevated size="lg" color="secondary" @click="submit" class="full-width text-white"
|
||||
:label="btnLabel" />
|
||||
</q-card-actions>
|
||||
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useQuasar } from 'quasar'
|
||||
// import { useRouter } from 'vue-router';
|
||||
import { ref } from 'vue';
|
||||
// import { Auth } from '../control/auth'
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
const authStore = useAuthStore();
|
||||
const $q = useQuasar()
|
||||
const loginForm = ref(null);
|
||||
let title = ref('ログイン');
|
||||
let email = ref('');
|
||||
let password = ref('');
|
||||
let visibility = ref(false);
|
||||
let passwordFieldType = ref('password');
|
||||
let visibilityIcon = ref('visibility');
|
||||
let btnLabel = ref('ログイン');
|
||||
const required = (val:string) => {
|
||||
return (val && val.length > 0 || '必須項目')
|
||||
}
|
||||
const isEmail = (val:string) => {
|
||||
const emailPattern = /^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/
|
||||
return (emailPattern.test(val) || '無効なメールアドレス')
|
||||
}
|
||||
const short = (val:string) => {
|
||||
return (val && val.length > 3 || '値が短く過ぎる')
|
||||
}
|
||||
const switchVisibility = () => {
|
||||
visibility.value = !visibility.value
|
||||
passwordFieldType.value = visibility.value ? 'text' : 'password'
|
||||
visibilityIcon.value = visibility.value ? 'visibility_off' : 'visibility'
|
||||
}
|
||||
const submit = () =>{
|
||||
authStore.login(email.value,password.value).then((result)=>{
|
||||
if(result)
|
||||
{
|
||||
$q.notify({
|
||||
icon: 'done',
|
||||
color: 'positive',
|
||||
message: 'ログイン成功'
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
$q.notify({
|
||||
icon: 'error',
|
||||
color: 'negative',
|
||||
message: 'ログイン失敗'
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
354
frontend/src/pages/UserDomain.vue
Normal file
354
frontend/src/pages/UserDomain.vue
Normal file
@@ -0,0 +1,354 @@
|
||||
<!-- <template>
|
||||
<div class="q-pa-md" style="max-width: 400px">
|
||||
|
||||
<q-form
|
||||
@submit="onSubmit"
|
||||
@reset="onReset"
|
||||
class="q-gutter-md"
|
||||
>
|
||||
<q-input
|
||||
filled
|
||||
v-model="name"
|
||||
label="Your name *"
|
||||
hint="Kintone envirment name"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0 || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
filled type="url"
|
||||
v-model="url"
|
||||
label="Kintone url"
|
||||
hint="Kintone domain address"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0,isDomain || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
filled
|
||||
v-model="username"
|
||||
label="Login user "
|
||||
hint="Kintone user name"
|
||||
lazy-rules
|
||||
:rules="[ val => val && val.length > 0 || 'Please type something']"
|
||||
/>
|
||||
|
||||
<q-input v-model="password" filled :type="isPwd ? 'password' : 'text'" hint="Password with toggle" label="User password">
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
:name="isPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="isPwd = !isPwd"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-toggle v-model="accept" label="Active Domain" />
|
||||
|
||||
<div>
|
||||
<q-btn label="Submit" type="submit" color="primary"/>
|
||||
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
|
||||
</div>
|
||||
</q-form>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { useQuasar } from 'quasar'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
setup () {
|
||||
const $q = useQuasar()
|
||||
|
||||
const name = ref(null)
|
||||
const age = ref(null)
|
||||
const accept = ref(false)
|
||||
const isPwd =ref(true)
|
||||
|
||||
return {
|
||||
name,
|
||||
age,
|
||||
accept,
|
||||
isPwd,
|
||||
isDomain(val) {
|
||||
const domainPattern = /^https?\/\/:([a-zA-Z] +\.){1}([a-zA-Z]+)\.([a-zA-Z]+)$/;
|
||||
return (domainPattern.test(val) || '無効なURL')
|
||||
},
|
||||
|
||||
onSubmit () {
|
||||
if (accept.value !== true) {
|
||||
$q.notify({
|
||||
color: 'red-5',
|
||||
textColor: 'white',
|
||||
icon: 'warning',
|
||||
message: 'You need to accept the license and terms first'
|
||||
})
|
||||
}
|
||||
else {
|
||||
$q.notify({
|
||||
color: 'green-4',
|
||||
textColor: 'white',
|
||||
icon: 'cloud_done',
|
||||
message: 'Submitted'
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReset () {
|
||||
name.value = null
|
||||
age.value = null
|
||||
accept.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script> -->
|
||||
|
||||
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table grid grid-header title="Domain" selection="single" :rows="rows" :columns="columns" v-model:selected="selected" row-key="name" :filter="filter" hide-header>
|
||||
<template v-slot:top>
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
<q-btn color="primary" size="sm" label=" 新規 " @click="newDomain()" dense />
|
||||
</div>
|
||||
<q-space />
|
||||
<q-input borderless dense debounce="300" v-model="filter" placeholder="Search">
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
<template v-slot:item="props">
|
||||
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-title">Name</div>
|
||||
<div class="q-table__grid-item-value">{{ props.row.name }}</div>
|
||||
</div>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-title">Domain</div>
|
||||
<div class="q-table__grid-item-value">{{ props.row.url }}</div>
|
||||
</div>
|
||||
<div class="q-table__grid-item-row">
|
||||
<div class="q-table__grid-item-title">Account</div>
|
||||
<div class="q-table__grid-item-value">{{ props.row.kintoneuser }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat @click = "editDomain(props.row)">編集</q-btn>
|
||||
<q-btn flat @click = "deleteConfirm(props.row)">削除</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-dialog :model-value="show" persistent>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">Kintone Account</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-pt-none">
|
||||
<q-form class="q-gutter-md">
|
||||
<q-input filled v-model="name" label="Your name *" hint="Kintone envirment name" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" />
|
||||
|
||||
<q-input filled type="url" v-model="url" label="Kintone url" hint="Kintone domain address" lazy-rules
|
||||
:rules="[val => val && val.length > 0, isDomain || 'Please type something']" />
|
||||
|
||||
<q-input filled v-model="kintoneuser" label="Login user " hint="Kintone user name" lazy-rules
|
||||
:rules="[val => val && val.length > 0 || 'Please type something']" />
|
||||
|
||||
<q-input v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'" hint="Password with toggle"
|
||||
label="User password">
|
||||
<template v-slot:append>
|
||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer" @click="isPwd = !isPwd" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-toggle v-model="active" label="Active Domain" />
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn label="Save" type="submit" color="primary" @click="onSubmit"/>
|
||||
<q-btn label="Cancel" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()"/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="confirm" persistent>
|
||||
<q-card>
|
||||
<q-card-section class="row items-center">
|
||||
<q-avatar icon="confirm" color="primary" text-color="white" />
|
||||
<span class="q-ml-sm">削除してもよろしいですか?</span>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat label="Cancel" color="primary" v-close-popup />
|
||||
<q-btn flat label="OK" color="primary" v-close-popup @click = "deleteDomain()"/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useQuasar } from 'quasar'
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
import { api } from 'boot/axios';
|
||||
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
const selected = ref([])
|
||||
const name = ref('')
|
||||
const active = ref(false)
|
||||
const isPwd =ref(true)
|
||||
const url =ref('')
|
||||
const kintoneuser =ref('')
|
||||
const kintonepwd =ref('')
|
||||
|
||||
const show = ref(false);
|
||||
const confirm = ref(false)
|
||||
|
||||
let editId = ref(0);
|
||||
|
||||
const columns = [
|
||||
{ name: 'id'},
|
||||
{
|
||||
name: 'name',
|
||||
required: true,
|
||||
label: 'Name',
|
||||
align: 'left',
|
||||
field: row => row.name,
|
||||
sortable: true
|
||||
},
|
||||
{ name: 'url', align: 'center', label: 'Domain', field: 'url', sortable: true },
|
||||
{ name: 'kintoneuser', label: 'User', field: 'kintoneuser', sortable: true },
|
||||
{ name: 'kintonepwd' }
|
||||
]
|
||||
|
||||
const rows = reactive([])
|
||||
|
||||
const newDomain = () => {
|
||||
editId.value = 0;
|
||||
show.value = true;
|
||||
};
|
||||
|
||||
const editDomain = (row:object) => {
|
||||
editId.value = row.id;
|
||||
name.value = row.name;
|
||||
url.value = row.url;
|
||||
kintoneuser.value = row.kintoneuser;
|
||||
kintonepwd.value = row.kintonepwd;
|
||||
isPwd.value = true;
|
||||
active.value = false;
|
||||
show.value = true;
|
||||
};
|
||||
|
||||
const deleteConfirm = (row:object) => {
|
||||
confirm.value = true;
|
||||
editId.value = row.id;
|
||||
};
|
||||
|
||||
const deleteDomain = () => {
|
||||
api.delete(`http://127.0.0.1:8000/api/domain/1/`+ editId.value).then(() =>{
|
||||
getDomain();
|
||||
})
|
||||
editId.value = 0;
|
||||
};
|
||||
|
||||
const closeDg = () => {
|
||||
show.value = false;
|
||||
onReset();
|
||||
};
|
||||
const getDomain = () => {
|
||||
api.get(`http://127.0.0.1:8000/api/domain/1`).then(res => {
|
||||
rows.length = 0;
|
||||
res.data.forEach((item) => {
|
||||
rows.push({ id:item.id,name: item.name, url: item.url, kintoneuser: item.kintoneuser, kintonepwd: item.kintonepwd });
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
onMounted(() => {
|
||||
getDomain();
|
||||
})
|
||||
|
||||
const isDomain = (val) =>{
|
||||
// const domainPattern = /^https\/\/:([a-zA-Z] +\.){1}([a-zA-Z]+)\.([a-zA-Z]+)$/;
|
||||
// return (domainPattern.test(val) || '無効なURL')
|
||||
return true;
|
||||
};
|
||||
|
||||
const onSubmit = () =>{
|
||||
if(editId.value !== 0)
|
||||
{
|
||||
api.put(`http://127.0.0.1:8000/api/domain`,{
|
||||
'id': editId.value,
|
||||
'userid': 1,
|
||||
'name': name.value,
|
||||
'url': url.value,
|
||||
'kintoneuser': kintoneuser.value,
|
||||
'kintonepwd': kintonepwd.value,
|
||||
'active': active.value
|
||||
}).then(() =>{
|
||||
getDomain();
|
||||
closeDg();
|
||||
onReset();
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
api.post(`http://127.0.0.1:8000/api/domain`,{
|
||||
'id': 0,
|
||||
'userid': 1,
|
||||
'name': name.value,
|
||||
'url': url.value,
|
||||
'kintoneuser': kintoneuser.value,
|
||||
'kintonepwd': kintonepwd.value,
|
||||
'active': active.value
|
||||
}).then(() =>{
|
||||
getDomain();
|
||||
closeDg();
|
||||
onReset();
|
||||
})
|
||||
}
|
||||
// if (accept.value !== true) {
|
||||
// $q.notify({
|
||||
// color: 'red-5',
|
||||
// textColor: 'white',
|
||||
// icon: 'warning',
|
||||
// message: 'You need to accept the license and terms first'
|
||||
// })
|
||||
// }
|
||||
// else {
|
||||
// $q.notify({
|
||||
// color: 'green-4',
|
||||
// textColor: 'white',
|
||||
// icon: 'cloud_done',
|
||||
// message: 'Submitted'
|
||||
// })
|
||||
// }
|
||||
};
|
||||
|
||||
const onReset = () => {
|
||||
name.value = '';
|
||||
url.value = '';
|
||||
kintoneuser.value = '';
|
||||
kintonepwd.value ='';
|
||||
isPwd.value = true;
|
||||
active.value = false;
|
||||
editId.value = 0;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from 'vue-router';
|
||||
|
||||
import routes from './routes';
|
||||
|
||||
import { useAuthStore } from 'stores/useAuthStore';
|
||||
/*
|
||||
* If not building with SSR mode, you can
|
||||
* directly export the Router instantiation;
|
||||
@@ -17,12 +17,31 @@ import routes from './routes';
|
||||
* with the Router instance.
|
||||
*/
|
||||
|
||||
export default route(function (/* { store, ssrContext } */) {
|
||||
const createHistory = process.env.SERVER
|
||||
// export default route(function (/* { store, ssrContext } */) {
|
||||
// const createHistory = process.env.SERVER
|
||||
// ? createMemoryHistory
|
||||
// : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory);
|
||||
|
||||
// const Router = createRouter({
|
||||
// scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
// routes,
|
||||
|
||||
// // Leave this as is and make changes in quasar.conf.js instead!
|
||||
// // quasar.conf.js -> build -> vueRouterMode
|
||||
// // quasar.conf.js -> build -> publicPath
|
||||
// history: createHistory(process.env.VUE_ROUTER_BASE),
|
||||
// });
|
||||
|
||||
// return Router;
|
||||
// });
|
||||
|
||||
|
||||
|
||||
const createHistory = process.env.SERVER
|
||||
? createMemoryHistory
|
||||
: (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory);
|
||||
|
||||
const Router = createRouter({
|
||||
export const Router = createRouter({
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
routes,
|
||||
|
||||
@@ -32,5 +51,23 @@ export default route(function (/* { store, ssrContext } */) {
|
||||
history: createHistory(process.env.VUE_ROUTER_BASE),
|
||||
});
|
||||
|
||||
export default route(function (/* { store, ssrContext } */) {
|
||||
return Router;
|
||||
});
|
||||
|
||||
Router.beforeEach(async (to) => {
|
||||
// clear alert on route change
|
||||
//const alertStore = useAlertStore();
|
||||
//alertStore.clear();
|
||||
|
||||
// redirect to login page if not logged in and trying to access a restricted page
|
||||
const publicPages = ['/login'];
|
||||
const authRequired = !publicPages.includes(to.path);
|
||||
const authStore = useAuthStore();
|
||||
|
||||
if (authRequired && !authStore.token) {
|
||||
authStore.returnUrl = to.fullPath;
|
||||
return '/login';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('pages/LoginPage.vue')
|
||||
},
|
||||
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('layouts/MainLayout.vue'),
|
||||
@@ -14,6 +19,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{ path: 'flowEditor2', component: () => import('pages/FlowChart.vue') },
|
||||
{ path: 'flowChart2', component: () => import('pages/FlowEditorPage2.vue') },
|
||||
{ path: 'right', component: () => import('pages/testRight.vue') },
|
||||
{ path: 'domain', component: () => import('pages/UserDomain.vue') }
|
||||
],
|
||||
},
|
||||
// Always leave this as last one,
|
||||
|
||||
36
frontend/src/stores/useAuthStore.ts
Normal file
36
frontend/src/stores/useAuthStore.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { api } from 'boot/axios';
|
||||
import { Router } from '../router';
|
||||
|
||||
|
||||
export const useAuthStore = defineStore({
|
||||
id: 'auth',
|
||||
state: () => ({
|
||||
token: localStorage.getItem('token'),
|
||||
returnUrl: ''
|
||||
}),
|
||||
actions: {
|
||||
async login(username:string, password:string) {
|
||||
const params = new URLSearchParams();
|
||||
params.append('username', username);
|
||||
params.append('password', password);
|
||||
try{
|
||||
const result = await api.post(`http://127.0.0.1:8000/api/token`,params);
|
||||
console.info(result);
|
||||
this.token =result.data.access_token;
|
||||
localStorage.setItem('token', result.data.access_token);
|
||||
Router.push(this.returnUrl || '/');
|
||||
return true;
|
||||
}catch(e)
|
||||
{
|
||||
console.info(e);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
this.token = null;
|
||||
localStorage.removeItem('token');
|
||||
Router.push('/login');
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user