Default user random pass, sqlite query patches

This commit is contained in:
KernelDeimos 2024-04-01 01:23:53 -04:00
parent 1cdda3dda8
commit 92b3f4ff76
4 changed files with 113 additions and 36 deletions

View File

@ -95,11 +95,8 @@ class Kernel extends AdvancedBase {
root_context.arun(async () => { root_context.arun(async () => {
await this._install_modules(); await this._install_modules();
});
(async () => {
await this._boot_services(); await this._boot_services();
})(); });
// Error.stackTraceLimit = Infinity; // Error.stackTraceLimit = Infinity;

View File

@ -1,7 +1,9 @@
const { surrounding_box } = require("../fun/dev-console-ui-utils"); const { surrounding_box } = require("../fun/dev-console-ui-utils");
const { get_user, generate_system_fsentries } = require("../helpers"); const { get_user, generate_system_fsentries, invalidate_cached_user } = require("../helpers");
const { Context } = require("../util/context");
const { asyncSafeSetInterval } = require("../util/promise"); const { asyncSafeSetInterval } = require("../util/promise");
const BaseService = require("./BaseService"); const BaseService = require("./BaseService");
const { Actor, UserActorType } = require("./auth/Actor");
const { DB_WRITE } = require("./database/consts"); const { DB_WRITE } = require("./database/consts");
const DEFAULT_PASSWORD = 'changeme'; const DEFAULT_PASSWORD = 'changeme';
@ -16,13 +18,24 @@ class DefaultUserService extends BaseService {
} }
async ['__on_ready.webserver'] () { async ['__on_ready.webserver'] () {
// check if a user named `default-user` exists // check if a user named `default-user` exists
let user = await get_user({ username: USERNAME }); let user = await get_user({ username: USERNAME, cached: false });
if ( ! user ) user = await this.create_default_user_(); if ( ! user ) user = await this.create_default_user_();
// check if user named `default-user` is using default password // check if user named `default-user` is using default password
const require = this.require; const require = this.require;
const tmp_password = await this.get_tmp_password_(user);
console.log(`second input [${tmp_password}]`);
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const is_default_password = await bcrypt.compare(DEFAULT_PASSWORD, user.password); console.log(...[
'THESE ARE THE ARGS',
tmp_password,
// password_hashed,
user.password
].map(l => l + '\n'));
const is_default_password = await bcrypt.compare(
tmp_password,
user.password
);
if ( ! is_default_password ) return; if ( ! is_default_password ) return;
// show console widget // show console widget
@ -30,23 +43,26 @@ class DefaultUserService extends BaseService {
const lines = [ const lines = [
`Your default user has been created!`, `Your default user has been created!`,
`\x1B[31;1musername:\x1B[0m ${USERNAME}`, `\x1B[31;1musername:\x1B[0m ${USERNAME}`,
`\x1B[32;1mpassword:\x1B[0m ${DEFAULT_PASSWORD}`, `\x1B[32;1mpassword:\x1B[0m ${tmp_password}`,
`(change the password to remove this message)` `(change the password to remove this message)`
]; ];
surrounding_box('31;1', lines); surrounding_box('31;1', lines);
return lines; return lines;
}; };
this.start_poll_(); this.start_poll_({ tmp_password, user });
const svc_devConsole = this.services.get('dev-console'); const svc_devConsole = this.services.get('dev-console');
svc_devConsole.add_widget(this.default_user_widget); svc_devConsole.add_widget(this.default_user_widget);
} }
start_poll_ () { start_poll_ ({ tmp_password, user }) {
const interval = 1000 * 3; // 3 seconds const interval = 1000 * 3; // 3 seconds
const poll_interval = asyncSafeSetInterval(async () => { const poll_interval = asyncSafeSetInterval(async () => {
const user = await get_user({ username: USERNAME }); const user = await get_user({ username: USERNAME });
const require = this.require; const require = this.require;
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const is_default_password = await bcrypt.compare(DEFAULT_PASSWORD, user.password); const is_default_password = await bcrypt.compare(
tmp_password,
user.password
);
if ( ! is_default_password ) { if ( ! is_default_password ) {
const svc_devConsole = this.services.get('dev-console'); const svc_devConsole = this.services.get('dev-console');
svc_devConsole.remove_widget(this.default_user_widget); svc_devConsole.remove_widget(this.default_user_widget);
@ -56,25 +72,53 @@ class DefaultUserService extends BaseService {
}, interval); }, interval);
} }
async create_default_user_ () { async create_default_user_ () {
const require = this.require;
const bcrypt = require('bcrypt');
const db = this.services.get('database').get(DB_WRITE, 'default-user'); const db = this.services.get('database').get(DB_WRITE, 'default-user');
await db.write( await db.write(
` `
INSERT INTO user (uuid, username, password, free_storage) INSERT INTO user (uuid, username, free_storage)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?)
`, `,
[ [
this.modules.uuidv4(), this.modules.uuidv4(),
USERNAME, USERNAME,
await bcrypt.hash(DEFAULT_PASSWORD, 8),
1024 * 1024 * 1024 * 10, // 10 GB 1024 * 1024 * 1024 * 10, // 10 GB
], ],
); );
const user = await get_user({ username: USERNAME }); const user = await get_user({ username: USERNAME });
const tmp_password = await this.get_tmp_password_(user);
console.log(`first input [${tmp_password}]`);
const bcrypt = require('bcrypt');
const password_hashed = await bcrypt.hash(tmp_password, 8);
await db.write(
`UPDATE user SET password = ? WHERE id = ?`,
[
password_hashed,
user.id,
],
);
user.password = password_hashed;
await generate_system_fsentries(user); await generate_system_fsentries(user);
invalidate_cached_user(user);
await new Promise(rslv => setTimeout(rslv, 2000));
return user; return user;
} }
async get_tmp_password_ (user) {
const actor = await Actor.create(UserActorType, { user });
return await Context.get().sub({ actor }).arun(async () => {
const svc_driver = this.services.get('driver');
const driver_response = await svc_driver.call(
'puter-kvstore', 'get', { key: 'tmp_password' });
if ( driver_response.result ) return driver_response.result.value;
const tmp_password = require('crypto').randomBytes(4).toString('hex');
await svc_driver.call(
'puter-kvstore', 'set', {
key: 'tmp_password',
value: tmp_password });
return tmp_password;
});
}
} }
module.exports = DefaultUserService; module.exports = DefaultUserService;

View File

@ -84,15 +84,28 @@ class DBKVStore extends BaseImplementation {
const db = this.services.get('database').get(DB_WRITE, 'kvstore'); const db = this.services.get('database').get(DB_WRITE, 'kvstore');
const key_hash = this.modules.murmurhash.v3(key); const key_hash = this.modules.murmurhash.v3(key);
try {
await db.write( await db.write(
`INSERT INTO kv `INSERT INTO kv (user_id, app, kkey_hash, kkey, value)
(user_id, app, kkey_hash, kkey, value) VALUES (?, ?, ?, ?, ?) ` +
VALUES db.case({
(?, ?, ?, ?, ?) mysql: 'ON DUPLICATE KEY UPDATE value = ?',
ON DUPLICATE KEY UPDATE sqlite: ' ',
value = ?`, // sqlite: 'ON CONFLICT(user_id, app, kkey_hash) DO UPDATE SET value = ?',
[ user.id, app?.uid ?? 'global', key_hash, key, value, value ] }),
[
user.id, app?.uid ?? 'global', key_hash, key, value,
...db.case({ mysql: [value], otherwise: [] }),
]
); );
} catch (e) {
// if ( e.code !== 'SQLITE_ERROR' && e.code !== 'SQLITE_CONSTRAINT_PRIMARYKEY' ) throw e;
// The "ON CONFLICT" clause isn't currently working.
await db.write(
`UPDATE kv SET value = ? WHERE user_id=? AND app=? AND kkey_hash=?`,
[ value, user.id, app?.uid ?? 'global', key_hash ]
);
}
return true; return true;
}, },

View File

@ -34,18 +34,41 @@ class MonthlyUsageService extends BaseService {
const maybe_app_id = actor.type.app?.id; const maybe_app_id = actor.type.app?.id;
if ( this.db.case({ sqlite: true, otherwise: false }) ) {
return;
}
// UPSERT increment count // UPSERT increment count
try {
await this.db.write( await this.db.write(
'INSERT INTO `service_usage_monthly` (`year`, `month`, `key`, `count`, `user_id`, `app_id`, `extra`) ' + 'INSERT INTO `service_usage_monthly` (`year`, `month`, `key`, `count`, `user_id`, `app_id`, `extra`) ' +
'VALUES (?, ?, ?, 1, ?, ?, ?) ' + 'VALUES (?, ?, ?, 1, ?, ?, ?) ' +
'ON DUPLICATE KEY UPDATE `count` = `count` + 1', this.db.case({
mysql: 'ON DUPLICATE KEY UPDATE `count` = `count` + 1, `extra` = ?',
sqlite: ' ',
// sqlite: 'ON CONFLICT(`year`, `month`, `key`, `user_id`, `app_id`) ' +
// 'DO UPDATE SET `count` = `count` + 1 AND `extra` = ?',
}),
[ [
year, month, key, year, month, key, actor.type.user.id, maybe_app_id, JSON.stringify(extra),
actor.type.user?.id || null, ...this.db.case({ mysql: [JSON.stringify(extra)], otherwise: [] }),
maybe_app_id || null,
JSON.stringify(extra)
] ]
); );
} catch (e) {
// if ( e.code !== 'SQLITE_ERROR' && e.code !== 'SQLITE_CONSTRAINT_PRIMARYKEY' ) throw e;
// The "ON CONFLICT" clause isn't currently working.
await this.db.write(
'UPDATE `service_usage_monthly` ' +
'SET `count` = `count` + 1, `extra` = ? ' +
'WHERE `year` = ? AND `month` = ? AND `key` = ? ' +
'AND `user_id` = ? AND `app_id` = ?',
[
JSON.stringify(extra),
year, month, key, actor.type.user.id, maybe_app_id,
]
);
}
} }
async check (actor, specifiers) { async check (actor, specifiers) {