Skip to content

Commit

Permalink
Type improvements (#2410)
Browse files Browse the repository at this point in the history
* started working on auto upgrade feature for adapters

* implemented full auto upgrade logic

* introduce logging to the auto upgrade manager

* make the processExit dummy a one liner

* also generate a notification for successful auto upgrades

* Filter out values with missing automaticUpgrade config

- optimize internal return type for GetObjectView on database level
- and fix types due to this
- and added some more types like for notifications

* fix missing generic arg

* updated the getObjectList types

* rm outcommented code

* group acl have users not user

* only auto upgrade if repo changed

* incorportate changes from PR #2279 but without the automatic upgrade functionality

* remove old methods not used externally and are just aliases internally

* improve getObjectView return types on db level

* fix some adaptions, because res is always defined on the promise based methods

- and rows is always there if we have a return value
- and also fix internal promise return type of getObjectList

* minor refacotring

* added blockedVersions to schema

- see #625

* also add blockedVersions to types

* filter out all null values instead of only parse errors

* clean up found usages of useless guards

* some more occurences
  • Loading branch information
foxriver76 authored Sep 3, 2023
1 parent 93e1145 commit 0b3c6e0
Show file tree
Hide file tree
Showing 22 changed files with 410 additions and 458 deletions.
95 changes: 49 additions & 46 deletions packages/adapter/src/lib/adapter/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1583,37 +1583,40 @@ export class AdapterClass extends EventEmitter {
}

private async _checkPassword(options: InternalCheckPasswordOptions): Promise<void> {
if (options.user && !options.user.startsWith('system.user.')) {
let { user } = options;
const { callback, pw } = options;

if (user && !user.startsWith('system.user.')) {
// it's not yet a `system.user.xy` id, thus we assume it's a username
if (!this.usernames[options.user]) {
if (!this.usernames[user]) {
// we did not find the id of the username in our cache -> update cache
try {
await this._updateUsernameCache();
} catch (e) {
this._logger.error(`${this.namespaceLog} ${e.message}`);
}
if (!this.usernames[options.user]) {
if (!this.usernames[user]) {
// user still not there, it's no valid user -> fallback to legacy check
options.user = `system.user.${options.user
user = `system.user.${user
.toString()
.replace(this.FORBIDDEN_CHARS, '_')
.replace(/\s/g, '_')
.replace(/\./g, '_')
.toLowerCase()}`;
} else {
options.user = this.usernames[options.user].id;
user = this.usernames[user].id;
}
} else {
options.user = this.usernames[options.user].id;
user = this.usernames[user].id;
}
}

this.getForeignObject(options.user, options, (err, obj) => {
if (err || !obj || !obj.common || (!obj.common.enabled && options.user !== SYSTEM_ADMIN_USER)) {
return tools.maybeCallback(options.callback, false, options.user);
this.getForeignObject(user, options, (err, obj) => {
if (err || !obj || !obj.common || (!obj.common.enabled && user !== SYSTEM_ADMIN_USER)) {
return tools.maybeCallback(callback, false, user);
} else {
password(options.pw).check(obj.common.password, (err, res) => {
return tools.maybeCallback(options.callback, !!res, options.user);
password(pw).check(obj.common.password, (err, res) => {
return tools.maybeCallback(callback, !!res, user);
});
}
});
Expand Down Expand Up @@ -1995,7 +1998,10 @@ export class AdapterClass extends EventEmitter {
private async _calculatePermissions(
options: InternalCalculatePermissionsOptions
): Promise<void | ioBroker.PermissionSet> {
if (options.user && !options.user.startsWith('system.user.')) {
const { user } = options;
let userId: ioBroker.ObjectIDs.User;

if (user && !user.startsWith('system.user.')) {
// it's not yet a `system.user.xy` id, thus we assume it's a username
if (!this.usernames[options.user]) {
// we did not find the id of the username in our cache -> update cache
Expand All @@ -2005,24 +2011,26 @@ export class AdapterClass extends EventEmitter {
this._logger.error(`${this.namespaceLog} ${e.message}`);
}
// user still not there, fallback
if (!this.usernames[options.user]) {
options.user = `system.user.${options.user
if (!this.usernames[user]) {
userId = `system.user.${user
.toString()
.replace(this.FORBIDDEN_CHARS, '_')
.replace(/\s/g, '_')
.replace(/\./g, '_')
.toLowerCase()}`;
} else {
options.user = this.usernames[options.user].id;
userId = this.usernames[user].id as ioBroker.ObjectIDs.User;
}
} else {
options.user = this.usernames[options.user].id;
userId = this.usernames[user].id as ioBroker.ObjectIDs.User;
}
} else {
userId = user as ioBroker.ObjectIDs.User;
}

// read all groups
let acl: Partial<ioBroker.PermissionSet> = { user: options.user };
if (options.user === SYSTEM_ADMIN_USER) {
let acl: Partial<ioBroker.PermissionSet> = { user: userId };
if (userId === SYSTEM_ADMIN_USER) {
acl.groups = [SYSTEM_ADMIN_GROUP];
for (const commandPermission of Object.values(options.commandsPermissions)) {
if (!commandPermission.type) {
Expand All @@ -2041,12 +2049,7 @@ export class AdapterClass extends EventEmitter {
// aggregate all groups permissions, where this user is
if (groups) {
for (const g of Object.keys(groups)) {
if (
groups[g] &&
groups[g].common &&
groups[g].common.members &&
groups[g].common.members.includes(options.user)
) {
if (groups[g]?.common?.members && groups[g].common.members.includes(userId)) {
acl.groups.push(groups[g]._id);
if (groups[g]._id === SYSTEM_ADMIN_GROUP) {
acl = {
Expand All @@ -2071,7 +2074,7 @@ export class AdapterClass extends EventEmitter {
create: true,
list: true
},
user: options.user,
user: userId,
users: {
read: true,
write: true,
Expand Down Expand Up @@ -3768,11 +3771,14 @@ export class AdapterClass extends EventEmitter {
}

// external signatures
getObjectList(params: ioBroker.GetObjectListParams | null, callback: ioBroker.GetObjectListCallback): void;
getObjectList(
params: ioBroker.GetObjectListParams | null,
callback: ioBroker.GetObjectListCallback<ioBroker.Object>
): void;
getObjectList(
params: ioBroker.GetObjectListParams | null,
options: { sorted?: boolean } | Record<string, any>,
callback: ioBroker.GetObjectListCallback
callback: ioBroker.GetObjectListCallback<ioBroker.Object>
): void;

/**
Expand Down Expand Up @@ -3902,7 +3908,7 @@ export class AdapterClass extends EventEmitter {
if (err) {
return tools.maybeCallbackWithError(callback, err);
}
if (res && res.rows) {
if (res?.rows) {
for (const row of res.rows) {
result[row.id] = row.value;
}
Expand Down Expand Up @@ -4040,7 +4046,7 @@ export class AdapterClass extends EventEmitter {
const result: {
[groupName: string]: Record<string, ioBroker.Enum>;
} = {};
if (res && res.rows) {
if (res?.rows) {
for (const row of res.rows) {
const parts: string[] = row.id.split('.', 3);
if (!parts[2]) {
Expand Down Expand Up @@ -4553,9 +4559,8 @@ export class AdapterClass extends EventEmitter {
// read all underlying states
adapterObjects!.getObjectList(selector, options, (err, res) => {
res &&
res.rows &&
res.rows.forEach(
(item: ioBroker.GetObjectListItem) =>
(item: ioBroker.GetObjectListItem<ioBroker.Object>) =>
!tasks.find(task => task.id === item.id) &&
(!item.value || !item.value.common || !item.value.common.dontDelete) && // exclude objects with dontDelete flag
tasks.push({ id: item.id, state: item.value && item.value.type === 'state' })
Expand All @@ -4569,7 +4574,7 @@ export class AdapterClass extends EventEmitter {
return tools.maybeCallbackWithError(callback, err);
} else if (obj) {
// do not allow deletion of objects with dontDelete flag
if (obj.common && obj.common.dontDelete) {
if (obj.common?.dontDelete) {
return tools.maybeCallbackWithError(callback, new Error('not deletable'));
}

Expand Down Expand Up @@ -5687,7 +5692,7 @@ export class AdapterClass extends EventEmitter {
return tools.maybeCallbackWithError(callback, err);
}

if (res && res.rows) {
if (res) {
for (const row of res.rows) {
try {
const obj = (await adapterObjects!.getObject(row.id, options)) as
Expand Down Expand Up @@ -6419,7 +6424,7 @@ export class AdapterClass extends EventEmitter {
},
options,
async (err, res) => {
if (err || !res || !res.rows) {
if (err || !res) {
return tools.maybeCallbackWithError(callback, err);
}

Expand Down Expand Up @@ -7176,7 +7181,7 @@ export class AdapterClass extends EventEmitter {
endkey: `${instanceName}.\u9999`
});

if (res?.rows) {
if (res) {
for (const row of res.rows) {
try {
await adapterStates!.pushMessage(row.id, obj);
Expand Down Expand Up @@ -7337,7 +7342,7 @@ export class AdapterClass extends EventEmitter {
// if states is no longer existing, we do not need to unsubscribe
return;
}
if (!err && res?.rows?.length) {
if (!err && res?.rows.length) {
for (const row of res.rows) {
const parts: string[] = row.id.split('.');
// ignore system.host.name.alive and so on
Expand Down Expand Up @@ -8915,7 +8920,7 @@ export class AdapterClass extends EventEmitter {

if (_obj?.rows) {
for (const row of _obj.rows) {
if (row.value.common && row.value.common.type === 'storage') {
if (row.value?.common && row.value.common.type === 'storage') {
this.defaultHistory = row.id.substring('system.adapter.'.length);
break;
}
Expand Down Expand Up @@ -9406,7 +9411,7 @@ export class AdapterClass extends EventEmitter {
options.checked = undefined;
}

if (!res || !res.rows) {
if (!res) {
return tools.maybeCallbackWithError(callback, null, {});
}
const keys = [];
Expand Down Expand Up @@ -10415,14 +10420,12 @@ export class AdapterClass extends EventEmitter {
endkey: 'system.adapter.\u9999'
});

if (res && res.rows) {
this.autoSubscribe = [];
for (const row of res.rows) {
if (row.value.common.subscribable) {
const _id = row.id.substring(15); // cut system.adapter.
if (!this.autoSubscribe.includes(_id)) {
this.autoSubscribe.push(_id);
}
this.autoSubscribe = [];
for (const row of res.rows) {
if (row.value?.common.subscribable) {
const _id = row.id.substring(15); // cut system.adapter.
if (!this.autoSubscribe.includes(_id)) {
this.autoSubscribe.push(_id);
}
}
}
Expand Down
6 changes: 1 addition & 5 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
export { execute } from './lib/setup';
export { dbConnectAsync } from './lib/setup/dbConnection';
// required by main.ts
export { Vendor } from './lib/setup/setupVendor';
// required by main.ts
export { Upload } from './lib/setup/setupUpload';
// required by testConsole
export { BackupRestore } from './lib/setup/setupBackup';
// used by adapter upgrade manager
export { Upgrade } from './lib/setup/setupUpgrade';
export { BackupRestore } from './lib/setup/setupBackup';
6 changes: 5 additions & 1 deletion packages/cli/src/lib/cli/cliObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,11 @@ export class CLIObjects extends CLICommand {
for (const type of types) {
try {
const res = await objects.getObjectViewAsync('system', type, params);
res?.rows.forEach(item => result.push(item.value));
res.rows.forEach(item => {
if (item.value) {
result.push(item.value);
}
});
} catch {
// ignore
}
Expand Down
11 changes: 5 additions & 6 deletions packages/cli/src/lib/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ async function processCommand(
endkey: `system.adapter.${instance}\u9999`
});

otherInstanceExists = !!res?.rows?.length;
otherInstanceExists = !!res.rows.length;
} catch {
// ignore - on install we have no object views
}
Expand Down Expand Up @@ -916,7 +916,7 @@ async function processCommand(
// @ts-expect-error todo check or handle null return value
const { stoppedList } = await install.downloadPacket(repoUrl, installName);
await install.installAdapter(installName, repoUrl);
await install.enableInstances(stoppedList, true); // even if unlikely make sure to reenable disabled instances
await install.enableInstances(stoppedList, true); // even if unlikely make sure to re-enable disabled instances
if (command !== 'install' && command !== 'i') {
await install.createInstance(name, params);
}
Expand Down Expand Up @@ -1182,8 +1182,7 @@ async function processCommand(
objects,
states,
params,
processExit: callback,
restartController
processExit: callback
});

if (adapter) {
Expand All @@ -1208,7 +1207,7 @@ async function processCommand(
} else {
// upgrade all
try {
const links = await getRepository(objects);
const links = await getRepository({ objects });
if (!links) {
return void callback(EXIT_CODES.INVALID_REPO);
}
Expand Down Expand Up @@ -2860,7 +2859,7 @@ async function cleanDatabase(isDeleteDb: boolean): Promise<number> {

try {
const res = await objects.getObjectListAsync({ startkey: '\u0000', endkey: '\u9999' });
if (res?.rows.length) {
if (res.rows.length) {
console.log(`clean ${res.rows.length} objects...`);
ids = res.rows.map(e => e.id);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/setup/setupBackup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface CLIBackupRestoreOptions {
restartController: RestartController;
}

type BackupObject = Omit<ioBroker.GetObjectListItem, 'doc'>;
type BackupObject = Omit<ioBroker.GetObjectListItem<ioBroker.Object>, 'doc'>;

export interface RestoreBackupReturnValue {
/** Exit code of the process */
Expand Down
Loading

0 comments on commit 0b3c6e0

Please sign in to comment.