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 () => {
await this._install_modules();
});
(async () => {
await this._boot_services();
})();
});
// Error.stackTraceLimit = Infinity;

View File

@ -1,7 +1,9 @@
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 BaseService = require("./BaseService");
const { Actor, UserActorType } = require("./auth/Actor");
const { DB_WRITE } = require("./database/consts");
const DEFAULT_PASSWORD = 'changeme';
@ -16,13 +18,24 @@ class DefaultUserService extends BaseService {
}
async ['__on_ready.webserver'] () {
// 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_();
// check if user named `default-user` is using default password
const require = this.require;
const tmp_password = await this.get_tmp_password_(user);
console.log(`second input [${tmp_password}]`);
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;
// show console widget
@ -30,23 +43,26 @@ class DefaultUserService extends BaseService {
const lines = [
`Your default user has been created!`,
`\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)`
];
surrounding_box('31;1', lines);
return lines;
};
this.start_poll_();
this.start_poll_({ tmp_password, user });
const svc_devConsole = this.services.get('dev-console');
svc_devConsole.add_widget(this.default_user_widget);
}
start_poll_ () {
start_poll_ ({ tmp_password, user }) {
const interval = 1000 * 3; // 3 seconds
const poll_interval = asyncSafeSetInterval(async () => {
const user = await get_user({ username: USERNAME });
const require = this.require;
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 ) {
const svc_devConsole = this.services.get('dev-console');
svc_devConsole.remove_widget(this.default_user_widget);
@ -56,25 +72,53 @@ class DefaultUserService extends BaseService {
}, interval);
}
async create_default_user_ () {
const require = this.require;
const bcrypt = require('bcrypt');
const db = this.services.get('database').get(DB_WRITE, 'default-user');
await db.write(
`
INSERT INTO user (uuid, username, password, free_storage)
VALUES (?, ?, ?, ?)
INSERT INTO user (uuid, username, free_storage)
VALUES (?, ?, ?)
`,
[
this.modules.uuidv4(),
USERNAME,
await bcrypt.hash(DEFAULT_PASSWORD, 8),
1024 * 1024 * 1024 * 10, // 10 GB
],
);
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);
invalidate_cached_user(user);
await new Promise(rslv => setTimeout(rslv, 2000));
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;

View File

@ -84,15 +84,28 @@ class DBKVStore extends BaseImplementation {
const db = this.services.get('database').get(DB_WRITE, 'kvstore');
const key_hash = this.modules.murmurhash.v3(key);
try {
await db.write(
`INSERT INTO kv
(user_id, app, kkey_hash, kkey, value)
VALUES
(?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
value = ?`,
[ user.id, app?.uid ?? 'global', key_hash, key, value, value ]
`INSERT INTO kv (user_id, app, kkey_hash, kkey, value)
VALUES (?, ?, ?, ?, ?) ` +
db.case({
mysql: 'ON DUPLICATE KEY UPDATE value = ?',
sqlite: ' ',
// sqlite: 'ON CONFLICT(user_id, app, kkey_hash) DO UPDATE SET 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;
},

View File

@ -34,18 +34,41 @@ class MonthlyUsageService extends BaseService {
const maybe_app_id = actor.type.app?.id;
if ( this.db.case({ sqlite: true, otherwise: false }) ) {
return;
}
// UPSERT increment count
try {
await this.db.write(
'INSERT INTO `service_usage_monthly` (`year`, `month`, `key`, `count`, `user_id`, `app_id`, `extra`) ' +
'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,
actor.type.user?.id || null,
maybe_app_id || null,
JSON.stringify(extra)
year, month, key, actor.type.user.id, maybe_app_id, JSON.stringify(extra),
...this.db.case({ mysql: [JSON.stringify(extra)], otherwise: [] }),
]
);
} 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) {