Skip to content

Commit

Permalink
feat: user profile + logout
Browse files Browse the repository at this point in the history
  • Loading branch information
NGPixel committed Mar 13, 2024
1 parent b9203a8 commit c40dbc2
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 18 deletions.
46 changes: 44 additions & 2 deletions src-electron/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default {
tokenUrl: 'https://auth.ietf.org/api/openid/token',
redirectUrl: 'https://draftforge.internal/oidc/callback',
userInfoUrl: 'https://auth.ietf.org/api/openid/userinfo',
logoutUrl: 'https://auth.ietf.org/api/openid/end-session',
scope: ['openid', 'profile', 'email', 'roles'],
accessToken: null,
refreshToken: null,
Expand Down Expand Up @@ -61,12 +62,12 @@ export default {
* @param {BrowserWindow} mainWindow - The main window of the application.
* @returns {Promise<void>} - A promise that resolves when the login process is complete.
*/
async login (mainWindow) {
async login () {
const state = crypto.randomUUID()

// -> Show login modal
const loginWindow = new BrowserWindow({
parent: mainWindow,
parent: this.refMainWindow,
modal: true,
width: 1024,
height: 768,
Expand Down Expand Up @@ -125,6 +126,47 @@ export default {
loginWindow.loadURL(`${this.authorizeUrl}?response_type=code&client_id=${this.clientId}&redirect_uri=${encodeURIComponent(this.redirectUrl)}&scope=${this.scope.join('%20')}&state=${state}`)
loginWindow.focus()
},
/**
* Logs out the user.
*/
logout () {
const endSessionJWT = this.jwt
this.clear()
this.persist()
this.notify()

// -> Logout from oidc provider
const logoutWindow = new BrowserWindow({
parent: this.refMainWindow,
modal: true,
width: 1024,
height: 768,
resizable: false,
minimizable: false,
maximizable: false,
fullscreenable: false,
title: 'Logout',
darkTheme: true,
show: false
})
// -> Intercept logout callback
logoutWindow.webContents.on('will-redirect', async ev => {
const evUrl = new URL(ev.url)
if (evUrl.hostname === 'draftforge.internal' && evUrl.pathname === '/oidc/callback') {
console.info('Logged out from OIDC provider.')
logoutWindow.close()
}
})
logoutWindow.setMenu(null)
logoutWindow.loadURL(`${this.logoutUrl}?id_token_hint=${endSessionJWT}&post_logout_redirect_uri=${encodeURIComponent(this.redirectUrl)}`)

// -> Success message
this.refMainWindow.webContents.send('notify', {
message: 'You are now logged out.',
color: 'positive',
icon: 'mdi-logout'
})
},
/**
* Refreshes the user information.
*
Expand Down
5 changes: 4 additions & 1 deletion src-electron/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,10 @@ export function registerCallbacks (mainWindow, mainMenu, auth, git, lsp) {
// AUTH
// ----------------------------------------------------------
ipcMain.on('login', () => {
auth.login(mainWindow)
auth.login()
})
ipcMain.on('logout', () => {
auth.logout()
})
ipcMain.on('authFetchInfo', () => {
auth.notify()
Expand Down
26 changes: 26 additions & 0 deletions src/components/MainToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ q-bar.toolbar-main
span.text-body2 {{ userStore.profile.name }}
q-avatar.q-ml-sm(size='sm' rounded)
img(:src='userStore.profile.picture')
q-menu(auto-close)
q-list.bg-light-blue-9(separator, style='min-width: 180px')
q-item.bg-dark-1
q-item-section.text-center
.text-caption.text-blue-grey-3 Datatracker Account
.text-caption.text-blue-grey-2: strong {{ userStore.profile.email }}
q-item(clickable, @click='openPrefProfile')
q-item-section(side)
q-icon(name='mdi-account-cog')
q-item-section Profile
q-item(clickable, @click='logout')
q-item-section(side)
q-icon(name='mdi-logout')
q-item-section Logout
q-btn(v-else padding="xs sm" flat no-caps @click='login')
span.text-body2 Login
q-icon.q-ml-sm(name='mdi-account-circle')
Expand Down Expand Up @@ -157,9 +171,21 @@ function openPreferences () {
})
}
function openPrefProfile () {
$q.dialog({
component: defineAsyncComponent(() => import('components/PreferencesDialog.vue')),
componentProps: {
tab: 'profile'
}
})
}
function login () {
window.ipcBridge.emit('login')
}
function logout () {
window.ipcBridge.emit('logout')
}
</script>

Expand Down
64 changes: 49 additions & 15 deletions src/components/PreferencesDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -192,20 +192,6 @@ q-dialog(

template(v-else-if='state.tab === `git`')
q-form.q-gutter-md.q-pa-lg
//- .row
//- .col-8
//- .text-body2 Git Mode
//- .text-caption.text-grey-5 Whether to use the system git or the editor built-in git integration.
//- .col-4
//- q-select(
//- outlined
//- v-model='editorStore.gitMode'
//- :options='gitModes'
//- dense
//- color='light-blue-4'
//- emit-value
//- map-options
//- )
.row
.col-8
.text-body2 Name
Expand Down Expand Up @@ -299,7 +285,43 @@ q-dialog(
)

template(v-else-if='state.tab === `profile`')
.q-pa-md: em Beep boop
.q-pa-md(v-if='userStore.isLoggedIn')
.row.q-gutter-md.items-center
.col-auto
q-avatar(size='70px', rounded)
img(:src='userStore.profile.picture')
.col
.text-caption: strong.text-grey-5 Logged in as
.text-body1 {{ userStore.profile.name }}
.text-body2 {{ userStore.profile.email }}
.col-auto
q-btn(
unelevated
color='primary'
label='Edit Profile'
icon='mdi-account-edit'
no-caps
@click='editProfile'
)
q-btn.q-ml-sm(
unelavated
color='negative'
label='Logout'
icon='mdi-logout'
no-caps
@click='logout'
)
.q-pa-md(v-else)
span You are not currently logged in.
.q-mt-md
q-btn(
unelevated
color='primary'
label='Login'
icon='mdi-login'
no-caps
@click='login'
)

template(v-if='state.tab === `dev`')
q-form.q-gutter-md.q-pa-lg
Expand All @@ -324,8 +346,10 @@ q-dialog(
import { defineAsyncComponent, onBeforeUnmount, reactive } from 'vue'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { useEditorStore } from 'src/stores/editor'
import { useUserStore } from 'src/stores/user'
const editorStore = useEditorStore()
const userStore = useUserStore()
const props = defineProps({
tab: {
Expand Down Expand Up @@ -509,6 +533,16 @@ function copyPublicKey () {
})
}
function login () {
window.ipcBridge.emit('login')
}
function editProfile () {
window.ipcBridge.emit('launchBrowser', { url: 'https://datatracker.ietf.org/accounts/profile/' })
}
function logout () {
window.ipcBridge.emit('logout')
}
onBeforeUnmount(() => {
editorStore.saveGitConfig()
})
Expand Down

0 comments on commit c40dbc2

Please sign in to comment.