Skip to content

Commit

Permalink
Store OBS websocket password using keytar.
Browse files Browse the repository at this point in the history
  • Loading branch information
grantjbutler committed Feb 5, 2022
1 parent f2fe8f9 commit f4a6813
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 35 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"core-js": "^3.6.5",
"data-uri-to-buffer": "^4.0.0",
"image-size": "^1.0.1",
"keytar": "^7.8.0",
"lodash": "^4.17.21",
"obs-websocket-js": "^4.0.3",
"on-change": "^3.0",
Expand Down
9 changes: 6 additions & 3 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ installInterface({
obsSocket
});

if (preferences.obsConnection) {
obsSocket.connect(preferences.obsConnection);
}
(async function() {
const savedConnection = await preferences.getObsConnection();
if (savedConnection) {
obsSocket.connect(savedConnection);
}
})();

let mainWindow: BrowserWindow | null = null;

Expand Down
8 changes: 4 additions & 4 deletions src/electron/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ export interface InstallationOptions {
}

export function install(options: InstallationOptions): void {
ipcMain.handle('load-obs-connection', () => {
return options.preferences.obsConnection
ipcMain.handle('load-obs-connection', async () => {
return await options.preferences.getObsConnection()
});

ipcMain.on('connect-to-obs', (_, connection: OBSConnectionOptions) => {
options.preferences.obsConnection = connection
ipcMain.on('connect-to-obs', async (_, connection: OBSConnectionOptions) => {
await options.preferences.setObsConnection(connection)

options.obsSocket.connect(connection);
});
Expand Down
28 changes: 16 additions & 12 deletions src/electron/preferences.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Store, StoreOptions } from './store'
import { safeStorage } from 'electron'
import { OBSConnectionOptions, isOBSConnectionOptions } from '@/obs/connection';
import keytar from 'keytar';

export default class Preferences {
store: Store
Expand All @@ -9,29 +10,32 @@ export default class Preferences {
this.store = new Store(options);
}

get obsConnection(): OBSConnectionOptions | null {
const connection = this.store.get('obs-connection');
if (isOBSConnectionOptions(connection)) {
if (connection.password) {
connection.password = safeStorage.decryptString(Buffer.from(connection.password, 'base64'))
}
async getObsConnection(): Promise<OBSConnectionOptions | null> {
const connection = this.store.get('obsConnection');
if (!isOBSConnectionOptions(connection)) { return null }

try {
connection.password = await keytar.getPassword('obs-websocket', 'obs') ?? undefined
} catch {
console.error('Could not fetch password from secure storage');

return connection;
connection.password = undefined
}

return null;
}

set obsConnection(value: OBSConnectionOptions | null) {
async setObsConnection(value: OBSConnectionOptions | null): Promise<void> {
if (value && value.password) {
value.password = safeStorage.encryptString(value.password).toString('base64')
await keytar.setPassword('obs-websocket', 'obs', value.password);
value.password = undefined
}

this.store.set('obs-connection', value)
this.store.set('obsConnection', value);
}

get sourceFilter(): string {
const sourceFilter = this.store.get('source-filter')
const sourceFilter = this.store.get('sourceFilter')
if (typeof sourceFilter !== 'string') {
return '';
}
Expand All @@ -40,6 +44,6 @@ export default class Preferences {
}

set sourceFilter(value: string) {
this.store.set('source-filter', value);
this.store.set('sourceFilter', value);
}
}
Loading

0 comments on commit f4a6813

Please sign in to comment.