Skip to content

Commit

Permalink
Merge pull request #68 from shvkhzod/logout-button
Browse files Browse the repository at this point in the history
Added Button to Logout in Settings
  • Loading branch information
shvkhzod authored Nov 23, 2023
2 parents 609c565 + d4b927c commit 0dfeb4a
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/application/i18n/messages/en.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"auth": {
"login": "Login"
"login": "Login",
"logout": "Logout"
},
"settings": {
"title": "Settings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ interface UseOAuthComposableState {
* Shows a popup window with google authorization
*/
showGoogleAuthPopup: () => void;
/**
* Logs out the user
*/
logout: () => Promise<void>;
}

/**
* Methods for working with OAuth (Google)
* Methods for working with Auth
*/
export default function useOAuth(): UseOAuthComposableState {
export default function useAuth(): UseOAuthComposableState {
/**
* Google OAuth URL
*/
Expand Down Expand Up @@ -54,8 +58,16 @@ export default function useOAuth(): UseOAuthComposableState {
}
});
}
/**
*Logs out the user by deleting the refresh token in local strorage
*/
async function logout(): Promise<void> {
await authService.logout();
}

return {
showGoogleAuthPopup,
logout,
};
}

4 changes: 3 additions & 1 deletion src/domain/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type AuthRepository from '@/domain/auth.repository.interface';
import type EventBus from '@/domain/event-bus';
import { AuthCompletedEvent } from './event-bus/events/AuthCompleted';
import UnauthorizedError from './entities/errors/Unauthorized';
import { AuthLogoutEvent } from './event-bus/events/AuthLogoutEvent';

/**
* Business logic for Authentication
Expand Down Expand Up @@ -62,8 +63,9 @@ export default class AuthService {
await this.repository.removeSession();

/**
* @todo dispatch AuthLogoutEvent to notify all listeners about logout
* Event to notify all listeners about logout
*/
this.eventBus.dispatchEvent(new AuthLogoutEvent());
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/domain/event-bus/events/AuthLogoutEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* The name of event
*/
export const AUTH_LOGOUT_EVENT_NAME = 'auth-logout';

/**
* Use cross domain events to explicitly implement side effects of changes within of a domain
*/
export class AuthLogoutEvent extends CustomEvent<null> {
/**
* Constructor options
*/
constructor() {
super(AUTH_LOGOUT_EVENT_NAME, {
detail: null,
});
}
}
2 changes: 2 additions & 0 deletions src/domain/event-bus/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { AUTH_COMPLETED_EVENT_NAME, AuthCompletedEvent } from './events/AuthCompleted';
import type { AUTH_LOGOUT_EVENT_NAME, AuthLogoutEvent } from './events/AuthLogoutEvent';

/**
* Event Bus provides a loosely coupled communication way between Domain and some other layers
Expand All @@ -12,6 +13,7 @@ export default class EventBus extends EventTarget {};
*/
export type CrossDomainEventMap = {
[AUTH_COMPLETED_EVENT_NAME]: AuthCompletedEvent;
[AUTH_LOGOUT_EVENT_NAME]: AuthLogoutEvent;
};

/**
Expand Down
5 changes: 5 additions & 0 deletions src/domain/user.repository.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export default interface UserRepositoryInterface {
*/
getUser: () => User | null;

/**
* Removes user data from the storage
*/
removeUser: () => Promise<void>;

/**
* Loads and store editor tools from user extensions
*/
Expand Down
7 changes: 7 additions & 0 deletions src/domain/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type UserRepository from '@/domain/user.repository.interface';
import type EventBus from '@/domain/event-bus';
import { AUTH_COMPLETED_EVENT_NAME } from './event-bus/events/AuthCompleted';
import type { User } from './entities/User';
import { AUTH_LOGOUT_EVENT_NAME } from './event-bus/events/AuthLogoutEvent';

/**
* Business logic for User
Expand All @@ -28,6 +29,12 @@ export default class UserService {
void this.repository.loadUser();
void this.repository.loadUserEditorTools();
});
/**
* When we got unauthorized
*/
eventBus.addEventListener(AUTH_LOGOUT_EVENT_NAME, () => {
void this.repository.removeUser();
});
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/infrastructure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import MarketplaceRepository from '@/infrastructure/marketplace.repository';
import { UserStore } from '@/infrastructure/storage/user';
import type EventBus from '@/domain/event-bus';
import { AUTH_COMPLETED_EVENT_NAME, type AuthCompletedEvent } from '@/domain/event-bus/events/AuthCompleted';
import { AUTH_LOGOUT_EVENT_NAME } from '@/domain/event-bus/events/AuthLogoutEvent';

/**
* Repositories
Expand Down Expand Up @@ -80,6 +81,16 @@ export function init(noteApiUrl: string, eventBus: EventBus): Repositories {
notesApiTransport.continueAnonymous();
}
});
/**
* When we got unauthorized
*/
eventBus.addEventListener(AUTH_LOGOUT_EVENT_NAME, () => {
/**
* Tell API transport to continue working in anonymous mode (send waiting requests without auth)
*/
authStore.removeRefreshToken();
notesApiTransport.continueAnonymous();
});

/**
* Init repositories
Expand Down
6 changes: 6 additions & 0 deletions src/infrastructure/storage/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class UserStore extends SubscribableStore<UserStoreData> {
this.data.user = user;
}

/**
* Removes user data
*/
public removeUser(): void {
this.data.user = null;
}
/**
* Array of tools
*/
Expand Down
7 changes: 7 additions & 0 deletions src/infrastructure/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export default class UserRepository extends Repository<UserStore, UserStoreData>
public getUser(): User | null {
return this.store.getUser();
}
/**
* Removes user data from the storage
*/
public async removeUser(): Promise<void> {
this.store.removeUser();
}

/**
* Load tools and set it
Expand Down Expand Up @@ -71,3 +77,4 @@ export default class UserRepository extends Repository<UserStore, UserStoreData>
console.log('Add tool response', response);
}
}

4 changes: 2 additions & 2 deletions src/presentation/components/header/HeaderLoginButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
import { IconUser } from '@codexteam/icons';
import { useI18n } from 'vue-i18n';
import Button from '@/presentation/components/button/Button.vue';
import useOAuth from '@/application/services/useOAuth';
import useAuth from '@/application/services/useAuth';
const { t } = useI18n();
const { showGoogleAuthPopup } = useOAuth();
const { showGoogleAuthPopup } = useAuth();
/**
* Shows Google Authentication in a popup
Expand Down
21 changes: 21 additions & 0 deletions src/presentation/pages/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
</li>
</ul>
<ThemeButton />
<Button
:text="t('auth.logout')"
type="primary"
:icon="IconUnlink"
@click="userLogout"
/>

<div class="add-tool">
<h2>
Expand All @@ -27,12 +33,18 @@

<script lang="ts" setup>
import { useI18n } from 'vue-i18n';
import Button from '../components/button/Button.vue';
import { IconUnlink } from '@codexteam/icons';
import { useRouter } from 'vue-router';
import useAuth from '@/application/services/useAuth';
import ThemeButton from '@/presentation/components/theme/ThemeButton.vue';
import { useAppState } from '@/application/services/useAppState';
import { useUserSettings } from '@/application/services/useUserSettings';
const { userEditorTools } = useAppState();
const { t } = useI18n();
const router = useRouter();
const { logout } = useAuth();
const { addTool: addToolToUser } = useUserSettings();
Expand All @@ -51,6 +63,15 @@ function addTool(event: KeyboardEvent): void {
}
}
/**
* Logs out the user
*/
async function userLogout() {
await logout().then(() => {
router.push({ path: '/' });
});
}
</script>

<style scoped>
Expand Down

0 comments on commit 0dfeb4a

Please sign in to comment.