Extract lightdm session logic into useLightdm composable

main
Warinyourself 3 weeks ago
parent 752dfc964c
commit ea715d5f1e

@ -3,6 +3,7 @@ import { useMagicKeys, useDebounceFn, whenever } from '@vueuse/core'
import { useAppStore } from '@/store/app'
import { usePageStore } from '@/store/page'
import { useQuerySync } from '@/composables/useQuerySync'
import { useLightdm, initLightdm } from '@/composables/useLightdm'
import { focusInputPassword, setCSSVariable } from '@/utils/helper'
import { hotkeys, toMagicKeyCombo } from '@/utils/hotkeys'
import { initTimer } from '@/utils/time'
@ -44,7 +45,7 @@ export default defineComponent({
whenever(keys.enter!, () => {
const isFocusPassword = document.querySelector('#password:focus')
if (isFocusPassword) {
appStore.login()
useLightdm().login()
} else {
focusInputPassword()
}
@ -52,6 +53,7 @@ export default defineComponent({
}
initTimer()
initLightdm()
appStore.setUpSettings()
useQuerySync()
initKeybinds()

@ -1,18 +1,20 @@
import { RotateCw, Moon, Snowflake } from '@lucide/vue'
import { defineComponent, computed } from 'vue'
import { systemActionsObject } from '@/utils/helper'
import { LightdmHandler } from '@/utils/lightdm'
import { useLightdm } from '@/composables/useLightdm'
const icons = { restart: RotateCw, suspend: Moon, hibernate: Snowflake }
export default defineComponent({
name: 'ShutdownMenu',
setup() {
const session = useLightdm()
const actions = computed(() =>
[
{ icon: 'restart', show: LightdmHandler.canRestart, callback: systemActionsObject.restart },
{ icon: 'suspend', show: LightdmHandler.canSuspend, callback: systemActionsObject.suspend },
{ icon: 'hibernate', show: LightdmHandler.canHibernate, callback: systemActionsObject.hibernate }
{ icon: 'restart', show: session.canRestart.value, callback: systemActionsObject.restart },
{ icon: 'suspend', show: session.canSuspend.value, callback: systemActionsObject.suspend },
{ icon: 'hibernate', show: session.canHibernate.value, callback: systemActionsObject.hibernate }
].filter(({ show }) => show)
)

@ -1,12 +1,12 @@
import { User } from '@lucide/vue'
import { defineComponent } from 'vue'
import { useAppStore } from '@/store/app'
import { useLightdm } from '@/composables/useLightdm'
import { usePageStore } from '@/store/page'
export default defineComponent({
name: 'UserAvatar',
setup() {
const appStore = useAppStore()
const session = useLightdm()
const pageStore = usePageStore()
const openSettings = () => {
@ -15,7 +15,7 @@ export default defineComponent({
}
return () => {
const user = appStore.currentUser
const user = session.currentUser.value
return (
<div class="user-choice" onClick={openSettings}>
{user?.image

@ -1,13 +1,13 @@
import { Settings, Eye, EyeOff, ArrowRight } from '@lucide/vue'
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/store/app'
import { usePageStore } from '@/store/page'
import { useLightdm } from '@/composables/useLightdm'
export default defineComponent({
name: 'UserInput',
setup() {
const appStore = useAppStore()
const session = useLightdm()
const pageStore = usePageStore()
const { t } = useI18n()
@ -18,29 +18,29 @@ export default defineComponent({
}
const handleKeyup = (event: KeyboardEvent) => {
appStore.password = (event.target as HTMLInputElement)?.value || ''
session.password.value = (event.target as HTMLInputElement)?.value || ''
}
return () => (
<div class="user-input">
<Settings class="settings-button" onClick={openSettings} />
<input
id="password"
type={appStore.showPassword ? 'text' : 'password'}
type={session.showPassword.value ? 'text' : 'password'}
name="password"
autocomplete="on"
autofocus
placeholder={t('text.password')}
onKeyup={handleKeyup}
value={appStore.password}
value={session.password.value}
/>
{appStore.showPassword
? <Eye class="icon icon-eye" onClick={() => appStore.toggleShowPassword()} />
: <EyeOff class="icon icon-eye" onClick={() => appStore.toggleShowPassword()} />}
{session.showPassword.value
? <Eye class="icon icon-eye" onClick={session.toggleShowPassword} />
: <EyeOff class="icon icon-eye" onClick={session.toggleShowPassword} />}
<button class="user-input-login" onClick={() => appStore.login()}>
<button class="user-input-login" onClick={session.login}>
<ArrowRight />
</button>
</div>

@ -2,8 +2,13 @@ import { defineComponent, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/store/app'
import { usePageStore } from '@/store/page'
import { useLightdm } from '@/composables/useLightdm'
import AppButtonGroup from '@/components/app/AppButtonGroup'
import { generateDesktopIcons, languageMap } from '@/utils/helper'
const languageFlags: Record<string, string> = {
en: '🇺🇸', es: '🇪🇸', fr: '🇫🇷', de: '🇩🇪', ru: '🇷🇺'
}
import { timePresets } from '@/utils/time'
const timeFormatItems = (Object.keys(timePresets) as Array<keyof typeof timePresets>).map((key) => ({
@ -15,11 +20,15 @@ export default defineComponent({
name: 'SettingsSelectors',
setup() {
const appStore = useAppStore()
const session = useLightdm()
const pageStore = usePageStore()
const { t, locale } = useI18n()
const languageList = computed(() =>
pageStore.languages.map((lang) => ({ text: languageMap[lang] || lang, value: lang }))
pageStore.languages.map((lang) => ({
value: lang,
text: [languageFlags[lang], languageMap[lang]].filter(Boolean).join(' ')
}))
)
const changeLanguage = (value: string) => {
@ -29,7 +38,8 @@ export default defineComponent({
}
const changeDesktop = (value: string) => {
appStore.saveStateApp({ key: 'desktop', value })
session.desktop.value = value
localStorage.setItem('desktop', value)
}
return () => (
@ -54,7 +64,7 @@ export default defineComponent({
block
label={t('settings.choice-desktop')}
items={generateDesktopIcons()}
modelValue={appStore.currentDesktop?.key}
modelValue={session.currentDesktop.value?.key}
onUpdate:modelValue={changeDesktop}
/>
</div>

@ -1,18 +1,18 @@
import { User } from '@lucide/vue'
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/store/app'
import { useLightdm } from '@/composables/useLightdm'
import type { LightdmUsers } from '@/models/lightdm'
export default defineComponent({
name: 'SettingsUsers',
setup() {
const appStore = useAppStore()
const session = useLightdm()
const { t } = useI18n()
const buildUserBlock = (user: LightdmUsers) => {
const isActive = user.username === appStore.username
const activateUser = () => { appStore.username = user.username }
const isActive = user.username === session.username.value
const activateUser = () => { session.username.value = user.username }
return (
<div onClick={activateUser} class={`settings-user-block ${isActive ? 'active' : ''}`}>
@ -27,7 +27,7 @@ export default defineComponent({
return () => (
<div>
<h2 class="title mb-1">{t('settings.users')}</h2>
<div class="users-grid">{appStore.users.map(buildUserBlock)}</div>
<div class="users-grid">{session.users.value.map(buildUserBlock)}</div>
</div>
)
}

@ -0,0 +1,116 @@
import { computed, ref } from 'vue'
import type { LightdmSession, LightdmUsers } from '@/models/lightdm'
const username = ref('')
const password = ref('')
const desktop = ref('')
const showPassword = ref(false)
const users = ref<LightdmUsers[]>([])
const desktops = ref<LightdmSession[]>([])
const canShutdown = ref(false)
const canRestart = ref(false)
const canSuspend = ref(false)
const canHibernate = ref(false)
const currentUser = computed(() => users.value.find((u) => u.username === username.value))
const currentDesktop = computed(() => desktops.value.find(({ key }) => key === desktop.value))
let _errorTimer: ReturnType<typeof setTimeout> | null = null
function _setInputError() {
const el = document.getElementById('password')
if (!el) return
el.classList.add('password-input--error')
if (_errorTimer) clearTimeout(_errorTimer)
_errorTimer = setTimeout(() => {
el.classList.remove('password-input--error')
_errorTimer = null
}, 10000)
}
function _setupSignals() {
window.lightdm?.show_message?.connect((text: string, type: any) => {
console.log({ text, type })
})
window.lightdm?.show_prompt?.connect((_message: string, type: number) => {
if (!window.lightdm) return
if (type === 0) {
window.lightdm.respond(username.value)
} else if (type === 1 && (window.lightdm as any).in_authentication) {
window.lightdm.respond(password.value)
}
})
window.lightdm?.authentication_complete?.connect(() => {
if (window.lightdm?.is_authenticated) {
window.lightdm.start_session(desktop.value || window.lightdm.default_session)
} else {
window.lightdm?.cancel_authentication()
_setInputError()
}
})
window.lightdm_cancel_login = () => window.lightdm?.cancel_authentication()
window.lightdm_start = (d: string) => window.lightdm?.start_session(d)
window.show_prompt = (text: string) => {
if (text === 'Password: ') window.lightdm?.respond(password.value)
}
window.authentication_complete = () => {
if (window.lightdm?.is_authenticated) {
window.lightdm_start(desktop.value)
} else if (document.head.dataset.wintype === 'primary') {
window.lightdm?.cancel_authentication()
}
}
}
export function initLightdm() {
users.value = (window.lightdm?.users || []) as LightdmUsers[]
desktops.value = (window.lightdm?.sessions || []) as LightdmSession[]
username.value = users.value[0]?.username || ''
desktop.value = window.lightdm?.default_session || desktops.value[0]?.key || ''
canShutdown.value = !!window.lightdm?.can_shutdown
canRestart.value = !!window.lightdm?.can_restart
canSuspend.value = !!window.lightdm?.can_suspend
canHibernate.value = !!window.lightdm?.can_hibernate
_setupSignals()
}
function login() {
window.lightdm?.authenticate(username.value)
}
function toggleShowPassword() {
showPassword.value = !showPassword.value
}
function shutdown() { window.lightdm?.shutdown() }
function hibernate() { window.lightdm?.hibernate() }
function suspend() { window.lightdm?.suspend() }
function restart() { window.lightdm?.restart() }
export function useLightdm() {
return {
username,
password,
desktop,
showPassword,
users,
desktops,
currentUser,
currentDesktop,
canShutdown,
canRestart,
canSuspend,
canHibernate,
login,
toggleShowPassword,
shutdown,
hibernate,
suspend,
restart,
}
}

@ -5,7 +5,7 @@ import { createI18n } from 'vue-i18n'
import App from './App'
import router from './router'
import { registerComponents } from '@/plugins/components'
import '@/utils/lightdm'
import '@/utils/lightdmMock'
import './style/index.styl'

@ -1,28 +1,22 @@
import { defineStore } from 'pinia'
import { computed, reactive, ref, type Ref } from 'vue'
import { computed, reactive, ref } from 'vue'
import type { AppSettings } from '@/models/app'
import type { LightdmSession, LightdmUsers } from '@/models/lightdm'
import { useThemeStore } from '@/store/theme'
import { LightdmHandler } from '@/utils/lightdm'
import { useLightdm } from '@/composables/useLightdm'
import { version as appVersion } from '../../package.json'
export const useAppStore = defineStore('app', () => {
const themeStore = useThemeStore()
const session = useLightdm()
const version = appVersion as string
const isGithubMode = import.meta.env.VITE_APP_VIEW === 'github'
const isDebugMode = import.meta.env.VITE_DEBUG === 'true'
const desktop = ref(LightdmHandler.defaultSession)
const username = ref(LightdmHandler.username)
const password = ref('')
const defaultColor = ref('#6BBBED')
const zoom = ref(1)
const users = ref(LightdmHandler.users as LightdmUsers[])
const desktops = ref(LightdmHandler.sessions as LightdmSession[])
const showPassword = ref(false)
const hotkeysEnabled = ref(false)
const showTime = ref(false)
const timeFormat = ref('HH:mm')
@ -34,14 +28,11 @@ export const useAppStore = defineStore('app', () => {
const showFrameRate = computed(() => bodyClass['show-framerate'])
const currentUser = computed(() => users.value.find((user) => user.username === username.value))
const currentDesktop = computed(() => desktops.value.find(({ key }) => key === desktop.value))
const getMainSettings = computed((): AppSettings => ({
zoom: zoom.value,
themes: themeStore.themes,
desktop: desktop.value,
username: username.value,
desktop: session.desktop.value,
username: session.username.value,
bodyClass,
currentTheme: themeStore.currentTheme,
defaultColor: defaultColor.value,
@ -50,30 +41,15 @@ export const useAppStore = defineStore('app', () => {
timeFormat: timeFormat.value,
}))
const personalInfo = computed(() => ({
username: username.value,
currentTheme: themeStore.currentTheme,
desktop: desktop.value,
version,
defaultColor: defaultColor.value
}))
const settableRefs: Record<string, Ref<any>> = { desktop, username, password, defaultColor, zoom }
function login() {
LightdmHandler.login(username.value, password.value, currentDesktop.value?.key)
}
function toggleShowPassword() {
showPassword.value = !showPassword.value
}
function changeBodyClass({ key, value }: { key: string; value: boolean }) {
bodyClass[key] = value
}
function saveStateApp({ key, value }: { key: string; value: string }) {
if (key in settableRefs) settableRefs[key]!.value = value
if (key === 'desktop') session.desktop.value = value
else if (key === 'username') session.username.value = value
else if (key === 'defaultColor') defaultColor.value = value
else if (key === 'zoom') zoom.value = parseFloat(value)
localStorage.setItem(key, value)
}
@ -87,14 +63,12 @@ export const useAppStore = defineStore('app', () => {
if (settings.themes) themeStore.syncThemeWithStore(settings)
const isExistDE = window.lightdm?.sessions.find(({ key }) => key === settings.desktop)
if (!isExistDE) settings.desktop = window.lightdm?.sessions[0]?.key || 'openbox'
const validDesktop = window.lightdm?.sessions.find(({ key }) => key === settings.desktop)?.key
session.desktop.value = validDesktop || window.lightdm?.sessions[0]?.key || 'openbox'
const isExistUser = window.lightdm?.users.find(({ username: name }) => name === settings.username)
if (!isExistUser) settings.username = window.lightdm?.users[0]?.username || 'Warinyourself'
const validUser = window.lightdm?.users.find(({ username }) => username === settings.username)?.username
session.username.value = validUser || window.lightdm?.users[0]?.username || ''
desktop.value = settings.desktop
username.value = settings.username
zoom.value = settings.zoom || 1
hotkeysEnabled.value = settings.hotkeysEnabled ?? false
showTime.value = settings.showTime ?? false
@ -108,28 +82,17 @@ export const useAppStore = defineStore('app', () => {
version,
isGithubMode,
isDebugMode,
desktop,
username,
password,
defaultColor,
zoom,
users,
desktops,
showPassword,
hotkeysEnabled,
showTime,
timeFormat,
bodyClass,
showFrameRate,
currentUser,
currentDesktop,
getMainSettings,
personalInfo,
login,
toggleShowPassword,
changeBodyClass,
saveStateApp,
syncSettingsWithCache,
setUpSettings
setUpSettings,
}
})

@ -8,7 +8,7 @@
background var(--background-block)
display flex
justify-content center
height var(--height-bar)
height 36px
align-items center
padding 0 var(--gap)

@ -22,7 +22,7 @@
justify-content center
.frame-rate-block
top calc(var(--gap) + var(--height-bar))
top var(--gap)
right var(--gap)
color white
font-size 1.1rem

@ -72,6 +72,7 @@
.user-choice
width 100%
cursor pointer
svg
width 50px
height 50px

@ -20,7 +20,7 @@
--glass-glow: 0 0 16px rgba(255, 255, 255, 0.35)
--gap: 12px
--zoom: 1
--height-bar: 36px
font-size 16px
::-webkit-scrollbar

@ -1,11 +1,10 @@
import type { RouteLocationRaw } from 'vue-router'
import router from '@/router'
import { LightdmHandler } from '@/utils/lightdm'
// Stores are imported statically but only CALLED inside functions/callbacks
// This is safe thanks to ES module live bindings (no circular dep issue at runtime)
import { useAppStore } from '@/store/app'
import { usePageStore } from '@/store/page'
import { useLightdm } from '@/composables/useLightdm'
export { setCSSVariable } from '@/utils/dom'
@ -53,7 +52,7 @@ export function getDesktopIcon(desktop = '') {
}
export function generateDesktopIcons() {
return useAppStore().desktops.map((desktop) => ({
return useLightdm().desktops.value.map((desktop) => ({
text: desktop.name,
value: desktop.key,
icon: getDesktopIcon(desktop.key)
@ -70,7 +69,7 @@ export function buildSystemDialog(callbackName: systemActionsType) {
title: `modals.${callbackName}.title`,
text: `modals.${callbackName}.text`,
actions: [
{ title: 'text.yes', callback: LightdmHandler[callbackName] },
{ title: 'text.yes', callback: () => useLightdm()[callbackName]() },
{ title: 'text.no', callback: () => pageStore.closeDialog() }
]
})

@ -1,6 +1,6 @@
import { usePageStore } from '@/store/page'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import { useLightdm } from '@/composables/useLightdm'
import { systemActionsObject, modKey } from '@/utils/helper'
const prefixTitle = 'settings.keyboard.'
@ -57,7 +57,7 @@ export const hotkeys = [
{
keys: [modKey, 'i'],
title: `${prefixTitle}show-password`,
callback: () => useAppStore().toggleShowPassword()
callback: () => useLightdm().toggleShowPassword()
},
{
keys: [modKey, 'P'],

@ -1,182 +0,0 @@
const DEBUG_PASSWORD = 'password'
const lightdmDebug = window.lightdm === undefined
function setIsAuthenticated(value: boolean) {
;(window.lightdm as any).is_authenticated = value
}
if (lightdmDebug) {
window.lightdm = {
is_authenticated: false,
authentication_user: undefined,
default_session: 'plasma-shell',
can_suspend: true,
can_restart: true,
can_hibernate: true,
can_shutdown: true,
authentication_complete: { connect: (callback: () => void) => { console.log('authentication complete') } },
sessions: [
{ name: 'GNOME', key: 'gnome-shell' },
{ name: 'KDE', key: 'plasma-shell' },
{ name: 'XFCE', key: 'xfce' },
{ name: 'Cinnamon', key: 'cinnamon' },
{ name: 'i3', key: 'i3' },
{ name: 'Openbox', key: 'openbox' },
],
users: [
{
display_name: 'Warinyourself',
username: 'Warinyourself',
image: 'https://avatars.githubusercontent.com/u/83131232?s=200&u=26fbedfe561a2b37225c78c10b1c5d67d6fe1832&v=4'
},
{ display_name: 'Bob', username: 'Bob' }
],
languages: [
{ name: 'Русский', code: 'ru_RU.utf8' },
{ name: 'American English', code: 'en_US.utf8' }
],
language: { code: 'en_US', name: 'American English' },
start_authentication: (username: string) => {
const inputNode = document.getElementById('password') as HTMLInputElement
window.lightdm?.respond(inputNode?.value || '')
},
authenticate: (username: string) => {
const inputNode = document.getElementById('password') as HTMLInputElement
if (window.lightdm) (window.lightdm as any).authentication_user = username
window.lightdm?.respond(inputNode?.value || '')
},
cancel_authentication: () => { console.log('Auth cancelled') },
start_session(session: string) { alert(`Start session: ${session}`) },
respond: (password: string) => {
if (password === DEBUG_PASSWORD) {
setIsAuthenticated(true)
} else {
setIsAuthenticated(false)
}
},
shutdown() { alert('(DEBUG: System is shutting down)') },
hibernate() { alert('(DEBUG: System is hibernating)') },
suspend: () => { alert('(DEBUG: System is suspending)') },
restart: () => { alert('(DEBUG: System is rebooting)') }
} as any
}
class LightdmWebkit {
protected _inputErrorTimer!: null | ReturnType<typeof setTimeout>
get defaultSession() {
return this.sessions[0]?.key || window.lightdm?.default_session || 'i3'
}
get sessions() { return window.lightdm?.sessions || [] }
get hasGuestAccount() { return window.lightdm?.has_guest_account }
get users() { return window.lightdm?.users || [] }
get username() { return this.users[0]?.username || 'Username' }
get languages() { return window.lightdm?.languages }
get canRestart() { return window.lightdm?.can_restart }
get canShutdown() { return window.lightdm?.can_shutdown }
get canSuspend() { return window.lightdm?.can_suspend }
get canHibernate() { return window.lightdm?.can_hibernate }
shutdown() { return window.lightdm?.shutdown() }
hibernate() { return window.lightdm?.hibernate() }
suspend() { return window.lightdm?.suspend() }
restart() { return window.lightdm?.restart() }
protected _setInputError() {
const inputNode = document.getElementById('password')
if (!inputNode) return
inputNode.classList.add('password-input--error')
if (this._inputErrorTimer) clearTimeout(this._inputErrorTimer)
this._inputErrorTimer = setTimeout(() => {
inputNode.classList.remove('password-input--error')
this._inputErrorTimer = null
}, 10000)
}
}
class LightdmNode extends LightdmWebkit {
public _username!: string
public _password!: string
public _session!: string
constructor() {
super()
this.init()
}
public login(username: string, password: string, session?: string): void {
this._username = username
this._password = password
this._session = session || this.defaultSession
window.lightdm?.authenticate(username)
}
public setAuthenticationDone(): void {
window.lightdm?.authentication_complete?.connect(() => {
if (window.lightdm?.is_authenticated) {
window.lightdm?.start_session(this._session || window.lightdm?.default_session)
} else {
this._authenticationFailed()
}
})
window.lightdm_cancel_login = () => {
window.lightdm?.cancel_authentication()
}
}
private _authenticationFailed(): void {
this._setInputError()
window.lightdm?.cancel_authentication()
}
public setSignalHandler(): void {
window.lightdm?.show_message?.connect(function (text, type) {
console.log({ text, type })
})
window.lightdm?.show_prompt?.connect((_message, type) => {
if (!window.lightdm) return
if (type === 0) {
window.lightdm.respond(this._username)
} else if (type === 1 && window.lightdm.in_authentication) {
window.lightdm.respond(this._password)
}
})
}
public init(): void {
this.setSignalHandler()
this.setAuthenticationDone()
}
}
export const LightdmHandler = new LightdmNode()
window.lightdm_cancel_login = () => {
window.lightdm?.cancel_authentication()
}
window.lightdm_start = (desktop: string) => {
window.lightdm?.start_session(desktop)
}
window.show_prompt = (text, type) => {
if (text === 'Password: ' && LightdmHandler._password !== undefined) {
window.lightdm?.respond(LightdmHandler._password)
}
}
window.authentication_complete = () => {
if (window.lightdm?.is_authenticated) {
window.lightdm_start(LightdmHandler._session)
} else if (document.head.dataset.wintype === 'primary') {
window.lightdm?.cancel_authentication()
}
}

@ -0,0 +1,55 @@
const DEBUG_PASSWORD = 'password'
if (window.lightdm === undefined) {
window.lightdm = {
is_authenticated: false,
authentication_user: undefined,
default_session: 'gnome-shell',
can_suspend: true,
can_restart: true,
can_hibernate: true,
can_shutdown: true,
authentication_complete: { connect: () => {} },
show_message: { connect: () => {} },
show_prompt: { connect: () => {} },
sessions: [
{ name: 'GNOME', key: 'gnome-shell' },
{ name: 'KDE', key: 'plasma-shell' },
{ name: 'XFCE', key: 'xfce' },
{ name: 'Cinnamon', key: 'cinnamon' },
{ name: 'i3', key: 'i3' },
{ name: 'Openbox', key: 'openbox' },
],
users: [
{
display_name: 'Warinyourself',
username: 'Warinyourself',
image: 'https://avatars.githubusercontent.com/u/83131232?s=200&u=26fbedfe561a2b37225c78c10b1c5d67d6fe1832&v=4'
},
{ display_name: 'Bob', username: 'Bob' }
],
languages: [
{ name: 'Русский', code: 'ru_RU.utf8' },
{ name: 'American English', code: 'en_US.utf8' }
],
language: { code: 'en_US', name: 'American English' },
authenticate: (username: string) => {
if (window.lightdm) (window.lightdm as any).authentication_user = username
const inputNode = document.getElementById('password') as HTMLInputElement
window.lightdm?.respond(inputNode?.value || '')
},
cancel_authentication: () => { console.log('Auth cancelled') },
start_session: (session: string) => { alert(`Start session: ${session}`) },
respond: (password: string) => {
;(window.lightdm as any).is_authenticated = password === DEBUG_PASSWORD
window.authentication_complete?.()
},
shutdown: () => { alert('(DEBUG: shutdown)') },
hibernate: () => { alert('(DEBUG: hibernate)') },
suspend: () => { alert('(DEBUG: suspend)') },
restart: () => { alert('(DEBUG: restart)') },
} as any
}
Loading…
Cancel
Save