mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 20:49:16 +00:00
enable logout from all devices in webapp
This commit is contained in:
parent
11fdcf621f
commit
b860494ca9
24
doc/api.oa3
24
doc/api.oa3
@ -913,30 +913,12 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: appName
|
- name: all
|
||||||
in: query
|
in: query
|
||||||
description: name of connecting app
|
description: whether all app tokens should be cleared
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: boolean
|
||||||
- name: appVersion
|
|
||||||
in: query
|
|
||||||
description: version of connecting app
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: platform
|
|
||||||
in: query
|
|
||||||
description: device platform
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: deviceToken
|
|
||||||
in: query
|
|
||||||
description: deviceToken for push notification
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: ok
|
description: ok
|
||||||
|
@ -10,6 +10,9 @@ import (
|
|||||||
//RemoveAgentToken
|
//RemoveAgentToken
|
||||||
func RemoveAgentToken(w http.ResponseWriter, r *http.Request) {
|
func RemoveAgentToken(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
// logout of all devices
|
||||||
|
logoutMode := r.FormValue("all") == "true"
|
||||||
|
|
||||||
// parse authentication token
|
// parse authentication token
|
||||||
target, access, err := ParseToken(r.FormValue("agent"))
|
target, access, err := ParseToken(r.FormValue("agent"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -17,30 +20,54 @@ func RemoveAgentToken(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// load session
|
if logoutMode {
|
||||||
var session store.Session
|
var sessions []store.Session
|
||||||
if err = store.DB.Where("account_id = ? AND token = ?", target, access).Find(&session).Error; err != nil {
|
if err = store.DB.Where("account_id = ?", target, access).Find(&sessions).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
ErrResponse(w, http.StatusNotFound, err);
|
|
||||||
} else {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err);
|
ErrResponse(w, http.StatusInternalServerError, err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete session
|
// delete all sessions
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := tx.Where("session_id = ?", session.ID).Delete(&store.PushEvent{}).Error; res != nil {
|
for _, session := range sessions {
|
||||||
return res
|
if res := tx.Where("session_id = ?", session.ID).Delete(&store.PushEvent{}).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if res := tx.Where("id = ?", session.ID).Delete(&store.Session{}).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if res := tx.Where("id = ?", session.ID).Delete(&store.Session{}).Error; res != nil {
|
} else {
|
||||||
return res
|
var session store.Session
|
||||||
|
if err = store.DB.Where("account_id = ? AND token = ?", target, access).Find(&session).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
ErrResponse(w, http.StatusNotFound, err);
|
||||||
|
} else {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete session
|
||||||
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
if res := tx.Where("session_id = ?", session.ID).Delete(&store.PushEvent{}).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if res := tx.Where("id = ?", session.ID).Delete(&store.Session{}).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteResponse(w, nil)
|
WriteResponse(w, nil)
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function clearLogin(token) {
|
export async function clearLogin(token, all) {
|
||||||
let logout = await fetchWithTimeout(`/account/apps?agent=${token}`, { method: 'DELETE' })
|
console.log("LOGOUT: ", token, all);
|
||||||
|
|
||||||
|
const param = all ? '&all=true' : ''
|
||||||
|
const logout = await fetchWithTimeout(`/account/apps?agent=${token}${param}`, { method: 'DELETE' })
|
||||||
checkResponse(logout)
|
checkResponse(logout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ export function useAppContext(websocket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
logout: async () => {
|
logout: async (all) => {
|
||||||
await appLogout();
|
await appLogout(all);
|
||||||
},
|
},
|
||||||
access: async (token) => {
|
access: async (token) => {
|
||||||
await appAccess(token)
|
await appAccess(token)
|
||||||
@ -140,10 +140,10 @@ export function useAppContext(websocket) {
|
|||||||
return access.created;
|
return access.created;
|
||||||
}
|
}
|
||||||
|
|
||||||
const appLogout = async () => {
|
const appLogout = async (all) => {
|
||||||
clearSession();
|
clearSession();
|
||||||
try {
|
try {
|
||||||
await clearLogin(appToken.current);
|
await clearLogin(appToken.current, all);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Modal, Dropdown, Menu, Tooltip } from 'antd';
|
import { useRef } from 'react';
|
||||||
|
import { Modal, Switch, Dropdown, Menu, Tooltip } from 'antd';
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
import { IdentityWrapper, ErrorNotice, InfoNotice } from './Identity.styled';
|
import { IdentityWrapper, LogoutContent, ErrorNotice, InfoNotice } from './Identity.styled';
|
||||||
import { useIdentity } from './useIdentity.hook';
|
import { useIdentity } from './useIdentity.hook';
|
||||||
import { LogoutOutlined, InfoCircleOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons';
|
import { LogoutOutlined, InfoCircleOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
@ -8,14 +9,19 @@ export function Identity({ openAccount, openCards, cardUpdated }) {
|
|||||||
|
|
||||||
const [modal, modalContext] = Modal.useModal();
|
const [modal, modalContext] = Modal.useModal();
|
||||||
const { state, actions } = useIdentity();
|
const { state, actions } = useIdentity();
|
||||||
|
const all = useRef(false);
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
modal.confirm({
|
modal.confirm({
|
||||||
title: 'Are you sure you want to logout?',
|
title: 'Are you sure you want to logout?',
|
||||||
icon: <LogoutOutlined />,
|
icon: <LogoutOutlined />,
|
||||||
|
content: <LogoutContent onClick={(e) => e.stopPropagation()}>
|
||||||
|
<span className="logoutMode">Logout of All Devices </span>
|
||||||
|
<Switch onChange={(e) => {all.current = e}} size="small" />
|
||||||
|
</LogoutContent>,
|
||||||
bodyStyle: { padding: 16 },
|
bodyStyle: { padding: 16 },
|
||||||
onOk() {
|
onOk() {
|
||||||
actions.logout();
|
actions.logout(all.current);
|
||||||
},
|
},
|
||||||
onCancel() {},
|
onCancel() {},
|
||||||
});
|
});
|
||||||
|
@ -60,6 +60,18 @@ export const IdentityWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const LogoutContent = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
.logoutMode {
|
||||||
|
padding-right: 8px;
|
||||||
|
color: ${Colors.text};
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export const ErrorNotice = styled.div`
|
export const ErrorNotice = styled.div`
|
||||||
color: ${Colors.alert};
|
color: ${Colors.alert};
|
||||||
`
|
`
|
||||||
|
@ -33,7 +33,9 @@ export function useIdentity() {
|
|||||||
}, [app.state]);
|
}, [app.state]);
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
logout: app.actions.logout,
|
logout: (all) => {
|
||||||
|
app.actions.logout(all);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return { state, actions };
|
return { state, actions };
|
||||||
|
Loading…
Reference in New Issue
Block a user