Files
dashback/scripts/manageUsers.js
2026-06-23 11:04:07 +02:00

155 lines
4.6 KiB
JavaScript

import React, { useState } from 'react';
import { render, Box, Text, useApp, useInput } from 'ink';
import TextInput from 'ink-text-input';
import chalk from 'chalk';
import * as googleAuth from '../src/db/googleAuth.js';
import '../src/config/env.js';
const e = React.createElement;
const MODES = {
MENU: 'menu',
ADD: 'add',
REMOVE: 'remove',
LIST: 'list',
DONE: 'done',
ERROR: 'error',
};
const Menu = ({ onSelect }) => {
const [selected, setSelected] = useState(0);
const options = [
{ label: 'List allowed emails', value: 'list' },
{ label: 'Add email', value: 'add' },
{ label: 'Remove email', value: 'remove' },
{ label: 'Quit', value: 'quit' },
];
useInput((_input, key) => {
if (key.upArrow) setSelected((s) => Math.max(0, s - 1));
if (key.downArrow) setSelected((s) => Math.min(options.length - 1, s + 1));
if (key.return) onSelect(options[selected].value);
});
return e(Box, { flexDirection: 'column' },
options.map((opt, i) =>
e(Text, { key: opt.value },
i === selected ? chalk.cyan('> ') : ' ',
i === selected ? chalk.cyan.bold(opt.label) : opt.label
)
)
);
};
const App = () => {
const { exit } = useApp();
const [mode, setMode] = useState(MODES.MENU);
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const [error, setError] = useState('');
const finish = (success, text) => {
if (success) {
setMessage(text);
setMode(MODES.DONE);
} else {
setError(text);
setMode(MODES.ERROR);
}
setTimeout(() => {
exit();
process.exit(success ? 0 : 1);
}, 100);
};
const handleMenu = (action) => {
if (action === 'quit') {
exit();
process.exit(0);
}
setEmail('');
setMode(action);
};
const handleAdd = () => {
try {
const trimmed = email.trim();
if (!trimmed || !trimmed.includes('@')) {
finish(false, 'Invalid email address');
return;
}
googleAuth.addAllowedEmail(trimmed);
finish(true, `Added ${trimmed.toLowerCase()} to google_auth`);
} catch (err) {
finish(false, err.message);
}
};
const handleRemove = () => {
try {
const trimmed = email.trim();
if (!trimmed) {
finish(false, 'Email is required');
return;
}
const removed = googleAuth.removeAllowedEmail(trimmed);
finish(true, removed ? `Removed ${trimmed.toLowerCase()}` : `Email not found: ${trimmed}`);
} catch (err) {
finish(false, err.message);
}
};
if (mode === MODES.DONE) {
return e(Text, null, chalk.green(message));
}
if (mode === MODES.ERROR) {
return e(Text, null, chalk.red(`Error: ${error}`));
}
if (mode === MODES.LIST) {
const emails = googleAuth.listAllowedEmails();
if (emails.length === 0) {
finish(true, 'No allowed emails in google_auth');
return e(Text, null, chalk.yellow('No allowed emails...'));
}
return e(Box, { flexDirection: 'column' },
e(Text, null, chalk.cyan.bold('Allowed emails:')),
...emails.map((row) => e(Text, { key: row.id }, ` ${row.email}`)),
e(Box, { marginTop: 1 }, e(Text, null, chalk.gray('Press any key to exit'))),
e(ExitOnKey, { onExit: () => { exit(); process.exit(0); } })
);
}
if (mode === MODES.ADD) {
return e(Box, { flexDirection: 'column' },
e(Text, null, chalk.cyan.bold('Add allowed email')),
e(Box, null,
e(Text, null, 'Email: '),
e(TextInput, { value: email, onChange: setEmail, onSubmit: handleAdd })
)
);
}
if (mode === MODES.REMOVE) {
return e(Box, { flexDirection: 'column' },
e(Text, null, chalk.cyan.bold('Remove allowed email')),
e(Box, null,
e(Text, null, 'Email: '),
e(TextInput, { value: email, onChange: setEmail, onSubmit: handleRemove })
)
);
}
return e(Box, { flexDirection: 'column' },
e(Box, { marginBottom: 1 },
e(Text, null, chalk.cyan.bold('=== Google Auth Email Manager ==='))
),
e(Menu, { onSelect: handleMenu })
);
};
const ExitOnKey = ({ onExit }) => {
useInput(onExit);
return null;
};
render(e(App));