From 9a6f8b86fcf740d98008b225178916c494bac8f8 Mon Sep 17 00:00:00 2001 From: Theo Salzmann Date: Fri, 3 Dec 2021 07:18:05 +0100 Subject: [PATCH] FEATURE: add plain text password toggle to settings (#22) * FEATURE: add plain text password toggle to settings * clean up state types, lint, and add migrate Co-authored-by: austinried <4966622+austinried@users.noreply.github.com> --- app/models/settings.ts | 12 +++++++- app/screens/ServerView.tsx | 59 +++++++++++++++++++++++++++++++++++--- app/state/migrations.ts | 11 +++++++ app/state/store.ts | 15 ++++++++++ app/subsonic/api.ts | 10 +++++-- package.json | 9 +----- 6 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 app/state/migrations.ts diff --git a/app/models/settings.ts b/app/models/settings.ts index a2487e4..9c77c8d 100644 --- a/app/models/settings.ts +++ b/app/models/settings.ts @@ -1,9 +1,19 @@ import { GetAlbumList2Type } from '@app/subsonic/params' -export interface Server { +export type Server = (TokenPassword | PlainPassword) & { id: string address: string username: string + usePlainPassword: boolean +} + +interface PlainPassword { + usePlainPassword: true + plainPassword: string +} + +interface TokenPassword { + usePlainPassword: false token: string salt: string } diff --git a/app/screens/ServerView.tsx b/app/screens/ServerView.tsx index ba32d95..f8c4e3f 100644 --- a/app/screens/ServerView.tsx +++ b/app/screens/ServerView.tsx @@ -11,6 +11,9 @@ import md5 from 'md5' import React, { useCallback, useState } from 'react' import { StyleSheet, Text, TextInput, View, ViewStyle } from 'react-native' import { v4 as uuidv4 } from 'uuid' +import SettingsSwitch from '@app/components/SettingsSwitch' + +const PASSWORD_PLACEHOLDER = 'PASSWORD_PLACEHOLDER' const ServerView: React.FC<{ id?: string @@ -26,7 +29,12 @@ const ServerView: React.FC<{ const [address, setAddress] = useState(server?.address || '') const [username, setUsername] = useState(server?.username || '') - const [password, setPassword] = useState(server?.token ? 'password' : '') + + const [usePlainPassword, setUsePlainPassword] = useState(server?.usePlainPassword ?? false) + const [password, setPassword] = useState( + server?.usePlainPassword ? server.plainPassword || '' : server?.token ? PASSWORD_PLACEHOLDER : '', + ) + const [testing, setTesting] = useState(false) const [removing, setRemoving] = useState(false) const [saving, setSaving] = useState(false) @@ -48,11 +56,24 @@ const ServerView: React.FC<{ }, [navigation]) const createServer = useCallback<() => Server>(() => { - const salt = server?.salt || uuidv4() + if (usePlainPassword) { + return { + id: server?.id || uuidv4(), + usePlainPassword, + plainPassword: password, + address, + username, + } + } + let token: string - if (password === 'password' && server?.token) { + let salt: string + + if (server && !server.usePlainPassword && password === PASSWORD_PLACEHOLDER) { + salt = server.salt token = server.token } else { + salt = uuidv4() token = md5(password + salt) } @@ -60,10 +81,11 @@ const ServerView: React.FC<{ id: server?.id || uuidv4(), address, username, + usePlainPassword, salt, token, } - }, [address, password, server?.id, server?.salt, server?.token, username]) + }, [usePlainPassword, server, address, username, password]) const save = useCallback(() => { if (!validate()) { @@ -105,6 +127,25 @@ const ServerView: React.FC<{ waitForRemove() }, [canRemove, exit, id, removeServer]) + const togglePlainPassword = useCallback( + (value: boolean) => { + setUsePlainPassword(value) + + if (value) { + if (server && server.usePlainPassword) { + setPassword(server.plainPassword) + } else if (server) { + setPassword('') + } + } else { + if (server && !server.usePlainPassword) { + setPassword(PASSWORD_PLACEHOLDER) + } + } + }, + [server], + ) + const test = useCallback(() => { setTesting(true) const potential = createServer() @@ -180,6 +221,16 @@ const ServerView: React.FC<{ value={password} onChangeText={setPassword} /> +