@iobroker/js-controller-common-db 7.2.2 → 7.2.3-alpha.1-20260621-61726ea22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/lib/common/logger.d.ts +17 -0
- package/build/cjs/lib/common/logger.js.map +2 -2
- package/build/cjs/lib/common/password.d.ts +9 -0
- package/build/cjs/lib/common/password.js.map +2 -2
- package/build/cjs/lib/common/session.js +3 -0
- package/build/cjs/lib/common/session.js.map +2 -2
- package/build/cjs/lib/common/tools.d.ts +65 -8
- package/build/cjs/lib/common/tools.js.map +2 -2
- package/build/esm/lib/common/logger.d.ts +17 -0
- package/build/esm/lib/common/logger.d.ts.map +1 -1
- package/build/esm/lib/common/logger.js +12 -2
- package/build/esm/lib/common/logger.js.map +1 -1
- package/build/esm/lib/common/password.d.ts +9 -0
- package/build/esm/lib/common/password.d.ts.map +1 -1
- package/build/esm/lib/common/password.js +5 -0
- package/build/esm/lib/common/password.js.map +1 -1
- package/build/esm/lib/common/session.d.ts.map +1 -1
- package/build/esm/lib/common/session.js +3 -0
- package/build/esm/lib/common/session.js.map +1 -1
- package/build/esm/lib/common/tools.d.ts +65 -8
- package/build/esm/lib/common/tools.d.ts.map +1 -1
- package/build/esm/lib/common/tools.js +37 -12
- package/build/esm/lib/common/tools.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import winston from 'winston';
|
|
2
2
|
export type LogInfo = Record<string | symbol, any>;
|
|
3
|
+
/** Logger configuration options provided by the user */
|
|
3
4
|
export interface UserOptions {
|
|
5
|
+
/** Minimum log level to output (e.g. silly, debug, info, warn, error) */
|
|
4
6
|
level: string;
|
|
7
|
+
/** Maximum number of days rotated log files are kept before deletion */
|
|
5
8
|
maxDays: number;
|
|
9
|
+
/** If true, do not output log messages to stdout */
|
|
6
10
|
noStdout: boolean;
|
|
11
|
+
/** Use local time instead of UTC for the log timestamps */
|
|
7
12
|
localTime?: string;
|
|
13
|
+
/** Colorize the console output */
|
|
8
14
|
colorize?: boolean;
|
|
15
|
+
/** Output log entries in JSON format */
|
|
9
16
|
json?: boolean;
|
|
17
|
+
/** Label prepended to every log message */
|
|
10
18
|
prefix?: string;
|
|
19
|
+
/** Winston transport configurations keyed by transport name */
|
|
11
20
|
transport: Record<string, any>;
|
|
12
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Create and configure a winston logger instance for the controller and adapters
|
|
24
|
+
*
|
|
25
|
+
* @param level Log level as a string, or a full UserOptions object with the detailed configuration
|
|
26
|
+
* @param files One or more log file paths the logger should write to
|
|
27
|
+
* @param noStdout If true, do not output log messages to stdout
|
|
28
|
+
* @param prefix Label prepended to every log message
|
|
29
|
+
*/
|
|
13
30
|
export declare function logger(level: string | UserOptions, files?: string[] | string, noStdout?: boolean, prefix?: string): winston.Logger;
|
|
14
31
|
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/logger.ts", "../../../../../../node_modules/@alcalzone/esm2cjs/shims/import.meta.url/shim.js"],
|
|
4
|
-
"sourcesContent": ["import winston from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport * as tools from '@/lib/common/tools.js';\nimport Transport from 'winston-transport';\nimport { LEVEL } from 'triple-beam';\nimport deepClone from 'deep-clone';\nimport type { Syslog } from 'winston-syslog';\nimport type { SeqTransport } from '@datalust/winston-seq';\nimport * as url from 'node:url';\nimport { createRequire } from 'node:module';\n\n// eslint-disable-next-line unicorn/prefer-module\nconst thisDir = url.fileURLToPath(new URL('.', import.meta.url || `file://${__filename}`));\n\n// eslint-disable-next-line unicorn/prefer-module\nconst require = createRequire(import.meta.url || `file://${__filename}`);\n\nconst hostname = tools.getHostName();\n\nlet SysLog: typeof Syslog | undefined;\ntry {\n SysLog = require('winston-syslog').Syslog;\n} catch {\n //console.log('No syslog support');\n}\n\nlet Seq: typeof SeqTransport | undefined;\ntry {\n Seq = require('@datalust/winston-seq').SeqTransport;\n} catch {\n //console.log('No seq support');\n}\n\nexport type LogInfo = Record<string | symbol, any>;\n\n// We must check if SysLog is defined before extending it\nconst IoSysLog =\n SysLog &&\n class extends SysLog {\n constructor(options: any) {\n super(options);\n }\n log(info: LogInfo, callback: () => void): void {\n // we need to map the ioBroker loglevels to the Syslog ones\n const ioInfo = info;\n if (ioInfo[LEVEL] === 'warn') {\n ioInfo[LEVEL] = 'warning';\n }\n if (ioInfo[LEVEL] === 'info') {\n ioInfo[LEVEL] = 'notice';\n }\n if (ioInfo[LEVEL] === 'debug') {\n ioInfo[LEVEL] = 'info';\n }\n if (ioInfo[LEVEL] === 'silly') {\n ioInfo[LEVEL] = 'debug';\n }\n\n // No clue why log could ever be undefined, but hey...\n super.log?.(ioInfo, callback);\n }\n };\n\n// We want to enhance some data for Seq\nconst IoSeq =\n Seq &&\n class extends Seq {\n log(info: LogInfo, callback: () => void): void {\n const ioInfo = deepClone(info);\n ioInfo.props = ioInfo.props || {};\n\n // map our log levels to Seq levels\n const level = (ioInfo.level || '').toLowerCase();\n if (level.includes('error')) {\n ioInfo.level = 'Error';\n } else if (level.includes('warn')) {\n ioInfo.level = 'Warning';\n } else if (level.includes('info')) {\n ioInfo.level = 'Information';\n } else if (level.includes('debug')) {\n ioInfo.level = 'Debug';\n } else if (level.includes('silly')) {\n ioInfo.level = 'Verbose';\n } else {\n ioInfo.level = 'Information';\n }\n\n // we add own properties\n ioInfo.props.Hostname = tools.getHostName();\n if (ioInfo.message) {\n // handle as single line with s flag, to if message ends with CR, etc\n const msgParts = ioInfo.message.match(/^([^.]+\\.[0-9]+) \\(([^)]+)\\) (.*)$/s);\n if (msgParts) {\n ioInfo.props.Source = msgParts[1];\n ioInfo.props.Pid = msgParts[2];\n } else {\n ioInfo.props.Source = 'js-controller';\n }\n }\n super.log(ioInfo, callback);\n }\n };\n\n// Class used to inform adapter about new log entry\nclass NotifierTransport extends Transport {\n private name: string;\n constructor(opts: any) {\n super(opts);\n this.name = 'NT'; // NotifierTransport\n }\n\n log(info: LogInfo, callback: () => void): void {\n const msg = {\n severity: info[LEVEL],\n ts: new Date(info.timestamp).getTime(),\n message: info.message,\n };\n setImmediate(() => this.emit('logged', msg));\n callback();\n }\n}\n\nexport interface UserOptions {\n level: string;\n maxDays: number;\n noStdout: boolean;\n localTime?: string;\n colorize?: boolean;\n json?: boolean;\n prefix?: string;\n transport: Record<string, any>;\n}\n\ninterface Options {\n format?: winston.Logform.Format;\n transports: Transport[];\n}\n\nexport function logger(\n level: string | UserOptions,\n files?: string[] | string,\n noStdout?: boolean,\n prefix?: string,\n): winston.Logger {\n const options: Options = {\n transports: [],\n };\n\n //var defaultMaxSize;// = 10 * 1024 * 1024;\n\n if (typeof files === 'string') {\n files = [files];\n }\n\n const formatter = (info: LogInfo): string => `${timestamp(info.timestamp)} - ${info.level}: ${info.message}`;\n\n files = files || [];\n\n // indicator which is used to determine the log dir for developing, where it should be inside the repository\n const isNpm = !thisDir\n .replace(/\\\\/g, '/')\n .toLowerCase()\n .includes(`${tools.appName.toLowerCase()}.js-controller/packages/`);\n\n if (tools.isObject(level)) {\n const userOptions: UserOptions = deepClone(level);\n\n level = userOptions.level;\n prefix = userOptions.prefix || '';\n noStdout = userOptions.noStdout;\n const winstonFormats = [];\n // @ts-expect-error formatter arg wrongly documented\n winstonFormats.push(winston.format.timestamp({ format: timestamp }));\n if (userOptions.json === undefined || userOptions.json) {\n winstonFormats.push(winston.format.json());\n }\n if (prefix) {\n winstonFormats.push(winston.format.label({ label: prefix }));\n }\n if (userOptions.colorize === undefined || userOptions.colorize) {\n winstonFormats.push(winston.format.colorize());\n }\n options.format = winston.format.combine.apply(null, winstonFormats);\n\n if (userOptions.prefix !== undefined) {\n delete userOptions.prefix;\n }\n\n if (userOptions.transport) {\n let fName = 0;\n const isWindows = os.platform().startsWith('win');\n for (const transport of Object.values(userOptions.transport)) {\n transport._defaultConfigLoglevel = transport.level; // remember Loglevel if set\n transport.level = transport.level || level;\n\n if (transport.type === 'file' && transport.enabled !== false) {\n transport.filename = transport.filename || `log/${tools.appName}`;\n\n if (!transport.fileext && transport.filename.indexOf('.log') === -1) {\n transport.fileext = '.log';\n }\n\n if (!fName) {\n transport.systemLog = true;\n }\n\n transport.handleExceptions = false;\n transport.name = fName ? `dailyRotateFile${fName}` : tools.appName;\n fName++;\n transport.filename = transport.filename.replace(/\\\\/g, '/');\n if (transport.filename.match(/^\\w:\\/|^\\//)) {\n transport.filename = path.normalize(transport.filename);\n } else {\n transport.filename = path.normalize(\n `${tools.getControllerDir()}${isNpm ? '/../../' : '/'}${transport.filename}`,\n );\n }\n transport.auditFile = `${transport.filename}-audit.json`;\n\n transport.createSymlink =\n transport.createSymlink !== undefined ? transport.createSymlink : !isWindows;\n transport.symlinkName =\n transport.symlinkName !== undefined\n ? transport.symlinkName\n : path.basename(`${transport.filename}.current.log`);\n\n transport.filename += `.%DATE%${transport.fileext || ''}`;\n //transport.label = prefix || ''; //TODO format.label()\n // transport.json = (transport.json !== undefined) ? transport.json : false; // TODO format.json(), new Default!!\n transport.silent = transport.silent !== undefined ? transport.silent : false;\n // transport.colorize = (transport.colorize !== undefined) ? transport.colorize : ((userOptions.colorize === undefined) ? true : userOptions.colorize); //TODO format.colorize()\n transport.localTime =\n transport.localTime !== undefined\n ? transport.localTime\n : userOptions.localTime === undefined\n ? true\n : userOptions.localTime;\n transport.datePattern = 'YYYY-MM-DD';\n transport.format = winston.format.combine(winston.format.printf(formatter));\n /*transport.logException = function (message, info, next, err) {\n console.error(message);\n };*/\n transport.zippedArchive = isWindows\n ? false\n : transport.zippedArchive !== undefined\n ? transport.zippedArchive\n : true;\n\n if (transport.maxFiles === null && userOptions.maxDays) {\n transport.maxFiles = `${userOptions.maxDays}d`;\n }\n\n try {\n const _log = new DailyRotateFile(transport);\n\n _log.on('error', err => {\n console.error(`Error on log file rotation: ${err.message}`);\n });\n\n options.transports.push(_log);\n } catch (e) {\n if (e.code === 'EACCES') {\n // modify error code to make it unique for handling\n e.code = 'EACCES_LOG';\n }\n throw e;\n }\n } else if (transport.type === 'syslog' && transport.enabled !== false) {\n if (!IoSysLog) {\n console.error('Syslog configured, but not installed! Ignore');\n continue;\n }\n // host: The host running syslogd, defaults to localhost.\n // port: The port on the host that syslog is running on, defaults to syslogd's default port.\n // protocol: The network protocol to log over (e.g. tcp4, udp4, unix, unix-connect, etc).\n // path: The path to the syslog dgram socket (i.e. /dev/log or /var/run/syslog for OS X).\n // pid: PID of the process that log messages are coming from (Default process.pid).\n // facility: Syslog facility to use (Default: local0).\n // localhost: Host to indicate that log messages are coming from (Default: localhost).\n // sysLogType: The type of the syslog protocol to use (Default: BSD).\n // app_name: The name of the application (Default: process.title).\n // eol: The end of line character to be added to the end of the message (Default: Message without modifications).\n // replace the used by syslog attribute \"type\" with own \"sysLogType\"\n\n // If no name defined, use hostname as name\n transport.localhost = transport.localhost || hostname;\n transport.format = winston.format.combine(winston.format.printf(formatter));\n if (transport.sysLogType) {\n transport.type = transport.sysLogType;\n delete transport.sysLogType;\n } else {\n delete transport.type;\n }\n try {\n options.transports.push(new IoSysLog(transport));\n } catch (e) {\n console.error(`Cannot activate Syslog: ${e.message}`);\n }\n } else if (transport.type === 'http' && transport.enabled !== false) {\n // host: (Default: localhost) Remote host of the HTTP logging endpoint\n // port: (Default: 80 or 443) Remote port of the HTTP logging endpoint\n // path: (Default: /) Remote URI of the HTTP logging endpoint\n // auth: (Default: None) An object representing the username and password for HTTP Basic Auth\n // ssl: (Default: false) Value indicating if we should use HTTPS\n\n // If no name defined, use hostname as name\n transport.host = transport.host || 'localhost';\n\n try {\n options.transports.push(new winston.transports.Http(transport));\n } catch (e) {\n console.error(`Cannot activate HTTP: ${e.message}`);\n }\n } else if (transport.type === 'stream' && transport.enabled !== false) {\n // stream: any Node.js stream. If an objectMode stream is provided then the entire info object will be written. Otherwise info[MESSAGE] will be written.\n // level: Level of messages that this transport should log (default: level set on parent logger).\n // silent: Boolean flag indicating whether to suppress output (default false).\n // eol: Line-ending character to use. (default: os.EOL).\n\n // If no name defined, use hostname as name\n transport.host = transport.host || 'localhost';\n\n try {\n if (typeof transport.stream === 'string') {\n transport.stream = fs.createWriteStream(transport.stream);\n transport.stream.on('error', (err: Error) => {\n console.error(`Error in Stream: ${err.message}`);\n });\n }\n\n options.transports.push(new winston.transports.Stream(transport));\n } catch (e) {\n console.error(`Cannot activate Stream: ${e.message}`);\n }\n } else if (transport.type === 'seq' && transport.enabled !== false) {\n if (!IoSeq) {\n console.error('Seq configured, but not installed! Ignore');\n continue;\n }\n // serverUrl?: string;\n // apiKey?: string;\n // maxBatchingTime?: number;\n // eventSizeLimit?: number;\n // batchSizeLimit?: number;\n\n // Add only if serverUrl is configured at least\n if (transport.serverUrl) {\n try {\n transport.onError = (e: Error) => {\n console.log(`SEQ error: ${e.message}`);\n };\n const seqLogger = new IoSeq(transport);\n options.transports.push(seqLogger);\n } catch (e) {\n console.error(`Cannot activate SEQ: ${e.message}`);\n }\n } else {\n console.error('Cannot activate SEQ: No serverUrl specified');\n }\n }\n }\n }\n } else {\n for (let i = 0; i < files.length; i++) {\n const opt = {\n name: i ? `dailyRotateFile${i}` : tools.appName,\n filename: path.normalize(\n isNpm ? `${thisDir}/../../../log/${files[i]}` : `${thisDir}/../log/${files[i]}`,\n ),\n extension: '.log',\n datePattern: 'YYYY-MM-DD',\n //json: false, // If true, messages will be logged as JSON (default true). TODO format.json()\n level,\n silent: false,\n localTime: true,\n //colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize, // TODO format.colorize()\n //timestamp: timestamp, // TODO: format.timestamp()\n //label: prefix || '', // TODO format.label()\n handleExceptions: false,\n //maxSize: defaultMaxSize\n };\n\n options.transports.push(new DailyRotateFile(opt));\n }\n }\n\n if (!noStdout) {\n options.transports.push(\n new winston.transports.Console({\n level,\n silent: false,\n format: winston.format.combine(winston.format.printf(formatter)),\n //colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize, // TODO format.colorize()\n //timestamp: timestamp, // TODO: format.timestamp()\n //label: prefix || '' // TODO format.label()\n }),\n );\n }\n\n // Must be registered, for adapter.js notification about new logs\n options.transports.push(\n new NotifierTransport({\n level,\n silent: false,\n }),\n );\n\n const log = winston.createLogger(options);\n\n // @ts-expect-error why do we override/add method to foreign instance? TODO\n log.getFileName = function () {\n // @ts-expect-error we use undocumented stuff here TODO\n let transport = this.transports.find(t => (t.transport && t.transport.dirname) || t.dirname);\n if (transport) {\n // @ts-expect-error we use undocumented stuff here TODO\n transport = transport.transport ? transport.transport : transport;\n // @ts-expect-error we use undocumented stuff here TODO\n return `${transport.dirname}/${transport.filename.replace('%DATE%', getDate())}`;\n }\n return '';\n };\n\n log.on('error', error => {\n console.log(`Logger error: ${error.message}`);\n });\n\n // This cannot be deleted, because file rotate works with the size of files and not with the time\n // TODO research and open new issue in winston-daily-rotate-file repo\n /**\n * @param isEnabled\n * @param daysCount\n */\n // @ts-expect-error why do we override/add method to foreign instance? TODO\n log.activateDateChecker = function (isEnabled, daysCount) {\n // @ts-expect-error we use undocumented stuff here TODO\n if (!isEnabled && this._fileChecker) {\n // @ts-expect-error we use undocumented stuff here TODO\n clearInterval(this._fileChecker);\n // @ts-expect-error we use undocumented stuff here TODO\n } else if (isEnabled && !this._fileChecker) {\n if (!daysCount) {\n daysCount = 3;\n }\n\n // Check every hour\n // @ts-expect-error we use undocumented stuff here TODO\n this._fileChecker = setInterval(() => {\n this.transports.forEach(transport => {\n if (\n // @ts-expect-error we use undocumented stuff here TODO\n transport.name !== 'dailyRotateFile' ||\n // @ts-expect-error we use undocumented stuff here TODO\n !transport.options ||\n // @ts-expect-error we use undocumented stuff here TODO\n transport.options.name !== tools.appName\n ) {\n return;\n }\n\n // @ts-expect-error we use undocumented stuff here TODO\n if (transport && fs.existsSync(transport.dirname)) {\n let files;\n try {\n // @ts-expect-error we use undocumented stuff here TODO\n files = fs.readdirSync(transport.dirname);\n } catch (e) {\n console.error(`host.${hostname} Cannot read log directory: ${e.message}`);\n return;\n }\n const forXdays = new Date();\n forXdays.setDate(forXdays.getDate() - daysCount - 1); // normally winston now takes care, for old or on errors make sure fallback works a day later\n\n for (let i = 0; i < files.length; i++) {\n const match = files[i].match(/.+\\.(\\d+-\\d+-\\d+)/);\n if (match) {\n const date = new Date(match[1]);\n if (date < forXdays) {\n // delete file\n try {\n this.log({\n level: 'info',\n message: `host.${hostname} Delete log file ${files[i]}`,\n });\n console.log(`host.${hostname} Delete log file ${files[i]}`);\n // @ts-expect-error we use undocumented stuff here TODO\n fs.unlinkSync(`${transport.dirname}/${files[i]}`);\n } catch (e) {\n // there is a bug under windows, that file stays opened and cannot be deleted\n this.log({\n level: os.platform().startsWith('win') ? 'info' : 'error',\n message: `host.${hostname} Cannot delete file \"${path.normalize(\n // @ts-expect-error we use undocumented stuff here TODO\n `${transport.dirname}/${files[i]}`,\n )}\": ${e}`,\n });\n console.log(\n `host.${hostname} Cannot delete file \"${path.normalize(\n // @ts-expect-error we use undocumented stuff here TODO\n `${transport.dirname}/${files[i]}`,\n )}\": ${e.message}`,\n );\n }\n }\n }\n }\n }\n });\n }, 3_600_000); // every hour\n }\n };\n\n return log;\n}\n\nfunction getDate(): string {\n const ts = new Date();\n return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, '0')}-${ts\n .getDate()\n .toString()\n .padStart(2, '0')}`;\n}\n\nfunction timestamp(date: string): string {\n const ts = date ? new Date(date) : new Date();\n return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, '0')}-${ts\n .getDate()\n .toString()\n .padStart(2, '0')} ${ts.getHours().toString().padStart(2, '0')}:${ts\n .getMinutes()\n .toString()\n .padStart(2, '0')}:${ts.getSeconds().toString().padStart(2, '0')}.${ts\n .getMilliseconds()\n .toString()\n .padStart(3, '0')} `;\n}\n", "export const __import_meta_url =\n typeof document === 'undefined' ? new (require('url'.replace('', '')).URL)('file:' + __filename).href :\n (document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href)\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;ACAO,IAAM,oBACX,OAAO,aAAa,cAAc,KAAK,QAAQ,MAAM,QAAQ,IAAI,EAAE,CAAC,GAAE,IAAK,UAAU,UAAU,EAAE,OAC9F,SAAS,iBAAiB,SAAS,cAAc,OAAO,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;ADFlG,qBAAoB;AACpB,uCAA4B;AAC5B,qBAAe;AACf,uBAAiB;AACjB,qBAAe;AACf,YAAuB;AACvB,+BAAsB;AACtB,yBAAsB;AACtB,wBAAsB;AAGtB,UAAqB;AACrB,yBAA8B;AAG9B,MAAM,UAAU,IAAI,cAAc,IAAI,IAAI,KAAK,qBAAmB,UAAU,UAAU,EAAE,CAAC;AAGzF,MAAMA,eAAU,kCAAc,qBAAmB,UAAU,UAAU,EAAE;AAEvE,MAAM,WAAW,MAAM,YAAW;AAElC,IAAI;AACJ,IAAI;AACA,WAASA,SAAQ,gBAAgB,EAAE;AACvC,QAAQ;AAER;AAEA,IAAI;AACJ,IAAI;AACA,QAAMA,SAAQ,uBAAuB,EAAE;AAC3C,QAAQ;AAER;AAKA,MAAM,WACF,UACA,cAAc,OAAM;EAChB,YAAY,SAAY;AACpB,UAAM,OAAO;EACjB;EACA,IAAI,MAAe,UAAoB;AAEnC,UAAM,SAAS;AACf,QAAI,OAAO,wBAAK,MAAM,QAAQ;AAC1B,aAAO,wBAAK,IAAI;IACpB;AACA,QAAI,OAAO,wBAAK,MAAM,QAAQ;AAC1B,aAAO,wBAAK,IAAI;IACpB;AACA,QAAI,OAAO,wBAAK,MAAM,SAAS;AAC3B,aAAO,wBAAK,IAAI;IACpB;AACA,QAAI,OAAO,wBAAK,MAAM,SAAS;AAC3B,aAAO,wBAAK,IAAI;IACpB;AAGA,UAAM,MAAM,QAAQ,QAAQ;EAChC;;AAIR,MAAM,QACF,OACA,cAAc,IAAG;EACb,IAAI,MAAe,UAAoB;AACnC,UAAM,aAAS,kBAAAC,SAAU,IAAI;AAC7B,WAAO,QAAQ,OAAO,SAAS,CAAA;AAG/B,UAAM,SAAS,OAAO,SAAS,IAAI,YAAW;AAC9C,QAAI,MAAM,SAAS,OAAO,GAAG;AACzB,aAAO,QAAQ;IACnB,WAAW,MAAM,SAAS,MAAM,GAAG;AAC/B,aAAO,QAAQ;IACnB,WAAW,MAAM,SAAS,MAAM,GAAG;AAC/B,aAAO,QAAQ;IACnB,WAAW,MAAM,SAAS,OAAO,GAAG;AAChC,aAAO,QAAQ;IACnB,WAAW,MAAM,SAAS,OAAO,GAAG;AAChC,aAAO,QAAQ;IACnB,OAAO;AACH,aAAO,QAAQ;IACnB;AAGA,WAAO,MAAM,WAAW,MAAM,YAAW;AACzC,QAAI,OAAO,SAAS;AAEhB,YAAM,WAAW,OAAO,QAAQ,MAAM,qCAAqC;AAC3E,UAAI,UAAU;AACV,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,MAAM,SAAS,CAAC;MACjC,OAAO;AACH,eAAO,MAAM,SAAS;MAC1B;IACJ;AACA,UAAM,IAAI,QAAQ,QAAQ;EAC9B;;AAIR,MAAM,0BAA0B,yBAAAC,QAAS;EAC7B;EACR,YAAY,MAAS;AACjB,UAAM,IAAI;AACV,SAAK,OAAO;EAChB;EAEA,IAAI,MAAe,UAAoB;AACnC,UAAM,MAAM;MACR,UAAU,KAAK,wBAAK;MACpB,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,QAAO;MACpC,SAAS,KAAK;;AAElB,iBAAa,MAAM,KAAK,KAAK,UAAU,GAAG,CAAC;AAC3C,aAAQ;EACZ;;
|
|
4
|
+
"sourcesContent": ["import winston from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport * as tools from '@/lib/common/tools.js';\nimport Transport from 'winston-transport';\nimport { LEVEL } from 'triple-beam';\nimport deepClone from 'deep-clone';\nimport type { Syslog } from 'winston-syslog';\nimport type { SeqTransport } from '@datalust/winston-seq';\nimport * as url from 'node:url';\nimport { createRequire } from 'node:module';\n\n// eslint-disable-next-line unicorn/prefer-module\nconst thisDir = url.fileURLToPath(new URL('.', import.meta.url || `file://${__filename}`));\n\n// eslint-disable-next-line unicorn/prefer-module\nconst require = createRequire(import.meta.url || `file://${__filename}`);\n\nconst hostname = tools.getHostName();\n\nlet SysLog: typeof Syslog | undefined;\ntry {\n SysLog = require('winston-syslog').Syslog;\n} catch {\n //console.log('No syslog support');\n}\n\nlet Seq: typeof SeqTransport | undefined;\ntry {\n Seq = require('@datalust/winston-seq').SeqTransport;\n} catch {\n //console.log('No seq support');\n}\n\nexport type LogInfo = Record<string | symbol, any>;\n\n// We must check if SysLog is defined before extending it\nconst IoSysLog =\n SysLog &&\n class extends SysLog {\n constructor(options: any) {\n super(options);\n }\n log(info: LogInfo, callback: () => void): void {\n // we need to map the ioBroker loglevels to the Syslog ones\n const ioInfo = info;\n if (ioInfo[LEVEL] === 'warn') {\n ioInfo[LEVEL] = 'warning';\n }\n if (ioInfo[LEVEL] === 'info') {\n ioInfo[LEVEL] = 'notice';\n }\n if (ioInfo[LEVEL] === 'debug') {\n ioInfo[LEVEL] = 'info';\n }\n if (ioInfo[LEVEL] === 'silly') {\n ioInfo[LEVEL] = 'debug';\n }\n\n // No clue why log could ever be undefined, but hey...\n super.log?.(ioInfo, callback);\n }\n };\n\n// We want to enhance some data for Seq\nconst IoSeq =\n Seq &&\n class extends Seq {\n log(info: LogInfo, callback: () => void): void {\n const ioInfo = deepClone(info);\n ioInfo.props = ioInfo.props || {};\n\n // map our log levels to Seq levels\n const level = (ioInfo.level || '').toLowerCase();\n if (level.includes('error')) {\n ioInfo.level = 'Error';\n } else if (level.includes('warn')) {\n ioInfo.level = 'Warning';\n } else if (level.includes('info')) {\n ioInfo.level = 'Information';\n } else if (level.includes('debug')) {\n ioInfo.level = 'Debug';\n } else if (level.includes('silly')) {\n ioInfo.level = 'Verbose';\n } else {\n ioInfo.level = 'Information';\n }\n\n // we add own properties\n ioInfo.props.Hostname = tools.getHostName();\n if (ioInfo.message) {\n // handle as single line with s flag, to if message ends with CR, etc\n const msgParts = ioInfo.message.match(/^([^.]+\\.[0-9]+) \\(([^)]+)\\) (.*)$/s);\n if (msgParts) {\n ioInfo.props.Source = msgParts[1];\n ioInfo.props.Pid = msgParts[2];\n } else {\n ioInfo.props.Source = 'js-controller';\n }\n }\n super.log(ioInfo, callback);\n }\n };\n\n// Class used to inform adapter about new log entry\nclass NotifierTransport extends Transport {\n private name: string;\n constructor(opts: any) {\n super(opts);\n this.name = 'NT'; // NotifierTransport\n }\n\n log(info: LogInfo, callback: () => void): void {\n const msg = {\n severity: info[LEVEL],\n ts: new Date(info.timestamp).getTime(),\n message: info.message,\n };\n setImmediate(() => this.emit('logged', msg));\n callback();\n }\n}\n\n/** Logger configuration options provided by the user */\nexport interface UserOptions {\n /** Minimum log level to output (e.g. silly, debug, info, warn, error) */\n level: string;\n /** Maximum number of days rotated log files are kept before deletion */\n maxDays: number;\n /** If true, do not output log messages to stdout */\n noStdout: boolean;\n /** Use local time instead of UTC for the log timestamps */\n localTime?: string;\n /** Colorize the console output */\n colorize?: boolean;\n /** Output log entries in JSON format */\n json?: boolean;\n /** Label prepended to every log message */\n prefix?: string;\n /** Winston transport configurations keyed by transport name */\n transport: Record<string, any>;\n}\n\ninterface Options {\n format?: winston.Logform.Format;\n transports: Transport[];\n}\n\n/**\n * Create and configure a winston logger instance for the controller and adapters\n *\n * @param level Log level as a string, or a full UserOptions object with the detailed configuration\n * @param files One or more log file paths the logger should write to\n * @param noStdout If true, do not output log messages to stdout\n * @param prefix Label prepended to every log message\n */\nexport function logger(\n level: string | UserOptions,\n files?: string[] | string,\n noStdout?: boolean,\n prefix?: string,\n): winston.Logger {\n const options: Options = {\n transports: [],\n };\n\n //var defaultMaxSize;// = 10 * 1024 * 1024;\n\n if (typeof files === 'string') {\n files = [files];\n }\n\n const formatter = (info: LogInfo): string => `${timestamp(info.timestamp)} - ${info.level}: ${info.message}`;\n\n files = files || [];\n\n // indicator which is used to determine the log dir for developing, where it should be inside the repository\n const isNpm = !thisDir\n .replace(/\\\\/g, '/')\n .toLowerCase()\n .includes(`${tools.appName.toLowerCase()}.js-controller/packages/`);\n\n if (tools.isObject(level)) {\n const userOptions: UserOptions = deepClone(level);\n\n level = userOptions.level;\n prefix = userOptions.prefix || '';\n noStdout = userOptions.noStdout;\n const winstonFormats = [];\n // @ts-expect-error formatter arg wrongly documented\n winstonFormats.push(winston.format.timestamp({ format: timestamp }));\n if (userOptions.json === undefined || userOptions.json) {\n winstonFormats.push(winston.format.json());\n }\n if (prefix) {\n winstonFormats.push(winston.format.label({ label: prefix }));\n }\n if (userOptions.colorize === undefined || userOptions.colorize) {\n winstonFormats.push(winston.format.colorize());\n }\n options.format = winston.format.combine.apply(null, winstonFormats);\n\n if (userOptions.prefix !== undefined) {\n delete userOptions.prefix;\n }\n\n if (userOptions.transport) {\n let fName = 0;\n const isWindows = os.platform().startsWith('win');\n for (const transport of Object.values(userOptions.transport)) {\n transport._defaultConfigLoglevel = transport.level; // remember Loglevel if set\n transport.level = transport.level || level;\n\n if (transport.type === 'file' && transport.enabled !== false) {\n transport.filename = transport.filename || `log/${tools.appName}`;\n\n if (!transport.fileext && transport.filename.indexOf('.log') === -1) {\n transport.fileext = '.log';\n }\n\n if (!fName) {\n transport.systemLog = true;\n }\n\n transport.handleExceptions = false;\n transport.name = fName ? `dailyRotateFile${fName}` : tools.appName;\n fName++;\n transport.filename = transport.filename.replace(/\\\\/g, '/');\n if (transport.filename.match(/^\\w:\\/|^\\//)) {\n transport.filename = path.normalize(transport.filename);\n } else {\n transport.filename = path.normalize(\n `${tools.getControllerDir()}${isNpm ? '/../../' : '/'}${transport.filename}`,\n );\n }\n transport.auditFile = `${transport.filename}-audit.json`;\n\n transport.createSymlink =\n transport.createSymlink !== undefined ? transport.createSymlink : !isWindows;\n transport.symlinkName =\n transport.symlinkName !== undefined\n ? transport.symlinkName\n : path.basename(`${transport.filename}.current.log`);\n\n transport.filename += `.%DATE%${transport.fileext || ''}`;\n //transport.label = prefix || ''; //TODO format.label()\n // transport.json = (transport.json !== undefined) ? transport.json : false; // TODO format.json(), new Default!!\n transport.silent = transport.silent !== undefined ? transport.silent : false;\n // transport.colorize = (transport.colorize !== undefined) ? transport.colorize : ((userOptions.colorize === undefined) ? true : userOptions.colorize); //TODO format.colorize()\n transport.localTime =\n transport.localTime !== undefined\n ? transport.localTime\n : userOptions.localTime === undefined\n ? true\n : userOptions.localTime;\n transport.datePattern = 'YYYY-MM-DD';\n transport.format = winston.format.combine(winston.format.printf(formatter));\n /*transport.logException = function (message, info, next, err) {\n console.error(message);\n };*/\n transport.zippedArchive = isWindows\n ? false\n : transport.zippedArchive !== undefined\n ? transport.zippedArchive\n : true;\n\n if (transport.maxFiles === null && userOptions.maxDays) {\n transport.maxFiles = `${userOptions.maxDays}d`;\n }\n\n try {\n const _log = new DailyRotateFile(transport);\n\n _log.on('error', err => {\n console.error(`Error on log file rotation: ${err.message}`);\n });\n\n options.transports.push(_log);\n } catch (e) {\n if (e.code === 'EACCES') {\n // modify error code to make it unique for handling\n e.code = 'EACCES_LOG';\n }\n throw e;\n }\n } else if (transport.type === 'syslog' && transport.enabled !== false) {\n if (!IoSysLog) {\n console.error('Syslog configured, but not installed! Ignore');\n continue;\n }\n // host: The host running syslogd, defaults to localhost.\n // port: The port on the host that syslog is running on, defaults to syslogd's default port.\n // protocol: The network protocol to log over (e.g. tcp4, udp4, unix, unix-connect, etc).\n // path: The path to the syslog dgram socket (i.e. /dev/log or /var/run/syslog for OS X).\n // pid: PID of the process that log messages are coming from (Default process.pid).\n // facility: Syslog facility to use (Default: local0).\n // localhost: Host to indicate that log messages are coming from (Default: localhost).\n // sysLogType: The type of the syslog protocol to use (Default: BSD).\n // app_name: The name of the application (Default: process.title).\n // eol: The end of line character to be added to the end of the message (Default: Message without modifications).\n // replace the used by syslog attribute \"type\" with own \"sysLogType\"\n\n // If no name defined, use hostname as name\n transport.localhost = transport.localhost || hostname;\n transport.format = winston.format.combine(winston.format.printf(formatter));\n if (transport.sysLogType) {\n transport.type = transport.sysLogType;\n delete transport.sysLogType;\n } else {\n delete transport.type;\n }\n try {\n options.transports.push(new IoSysLog(transport));\n } catch (e) {\n console.error(`Cannot activate Syslog: ${e.message}`);\n }\n } else if (transport.type === 'http' && transport.enabled !== false) {\n // host: (Default: localhost) Remote host of the HTTP logging endpoint\n // port: (Default: 80 or 443) Remote port of the HTTP logging endpoint\n // path: (Default: /) Remote URI of the HTTP logging endpoint\n // auth: (Default: None) An object representing the username and password for HTTP Basic Auth\n // ssl: (Default: false) Value indicating if we should use HTTPS\n\n // If no name defined, use hostname as name\n transport.host = transport.host || 'localhost';\n\n try {\n options.transports.push(new winston.transports.Http(transport));\n } catch (e) {\n console.error(`Cannot activate HTTP: ${e.message}`);\n }\n } else if (transport.type === 'stream' && transport.enabled !== false) {\n // stream: any Node.js stream. If an objectMode stream is provided then the entire info object will be written. Otherwise info[MESSAGE] will be written.\n // level: Level of messages that this transport should log (default: level set on parent logger).\n // silent: Boolean flag indicating whether to suppress output (default false).\n // eol: Line-ending character to use. (default: os.EOL).\n\n // If no name defined, use hostname as name\n transport.host = transport.host || 'localhost';\n\n try {\n if (typeof transport.stream === 'string') {\n transport.stream = fs.createWriteStream(transport.stream);\n transport.stream.on('error', (err: Error) => {\n console.error(`Error in Stream: ${err.message}`);\n });\n }\n\n options.transports.push(new winston.transports.Stream(transport));\n } catch (e) {\n console.error(`Cannot activate Stream: ${e.message}`);\n }\n } else if (transport.type === 'seq' && transport.enabled !== false) {\n if (!IoSeq) {\n console.error('Seq configured, but not installed! Ignore');\n continue;\n }\n // serverUrl?: string;\n // apiKey?: string;\n // maxBatchingTime?: number;\n // eventSizeLimit?: number;\n // batchSizeLimit?: number;\n\n // Add only if serverUrl is configured at least\n if (transport.serverUrl) {\n try {\n transport.onError = (e: Error) => {\n console.log(`SEQ error: ${e.message}`);\n };\n const seqLogger = new IoSeq(transport);\n options.transports.push(seqLogger);\n } catch (e) {\n console.error(`Cannot activate SEQ: ${e.message}`);\n }\n } else {\n console.error('Cannot activate SEQ: No serverUrl specified');\n }\n }\n }\n }\n } else {\n for (let i = 0; i < files.length; i++) {\n const opt = {\n name: i ? `dailyRotateFile${i}` : tools.appName,\n filename: path.normalize(\n isNpm ? `${thisDir}/../../../log/${files[i]}` : `${thisDir}/../log/${files[i]}`,\n ),\n extension: '.log',\n datePattern: 'YYYY-MM-DD',\n //json: false, // If true, messages will be logged as JSON (default true). TODO format.json()\n level,\n silent: false,\n localTime: true,\n //colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize, // TODO format.colorize()\n //timestamp: timestamp, // TODO: format.timestamp()\n //label: prefix || '', // TODO format.label()\n handleExceptions: false,\n //maxSize: defaultMaxSize\n };\n\n options.transports.push(new DailyRotateFile(opt));\n }\n }\n\n if (!noStdout) {\n options.transports.push(\n new winston.transports.Console({\n level,\n silent: false,\n format: winston.format.combine(winston.format.printf(formatter)),\n //colorize: (userOptions.colorize === undefined) ? true : userOptions.colorize, // TODO format.colorize()\n //timestamp: timestamp, // TODO: format.timestamp()\n //label: prefix || '' // TODO format.label()\n }),\n );\n }\n\n // Must be registered, for adapter.js notification about new logs\n options.transports.push(\n new NotifierTransport({\n level,\n silent: false,\n }),\n );\n\n const log = winston.createLogger(options);\n\n // @ts-expect-error why do we override/add method to foreign instance? TODO\n log.getFileName = function () {\n // @ts-expect-error we use undocumented stuff here TODO\n let transport = this.transports.find(t => (t.transport && t.transport.dirname) || t.dirname);\n if (transport) {\n // @ts-expect-error we use undocumented stuff here TODO\n transport = transport.transport ? transport.transport : transport;\n // @ts-expect-error we use undocumented stuff here TODO\n return `${transport.dirname}/${transport.filename.replace('%DATE%', getDate())}`;\n }\n return '';\n };\n\n log.on('error', error => {\n console.log(`Logger error: ${error.message}`);\n });\n\n // This cannot be deleted, because file rotate works with the size of files and not with the time\n // TODO research and open new issue in winston-daily-rotate-file repo\n /**\n * Enable or disable the periodic checker that deletes outdated log files\n *\n * @param isEnabled Whether the periodic file checker should run\n * @param daysCount Number of days after which old log files are deleted (defaults to 3)\n */\n // @ts-expect-error why do we override/add method to foreign instance? TODO\n log.activateDateChecker = function (isEnabled, daysCount) {\n // @ts-expect-error we use undocumented stuff here TODO\n if (!isEnabled && this._fileChecker) {\n // @ts-expect-error we use undocumented stuff here TODO\n clearInterval(this._fileChecker);\n // @ts-expect-error we use undocumented stuff here TODO\n } else if (isEnabled && !this._fileChecker) {\n if (!daysCount) {\n daysCount = 3;\n }\n\n // Check every hour\n // @ts-expect-error we use undocumented stuff here TODO\n this._fileChecker = setInterval(() => {\n this.transports.forEach(transport => {\n if (\n // @ts-expect-error we use undocumented stuff here TODO\n transport.name !== 'dailyRotateFile' ||\n // @ts-expect-error we use undocumented stuff here TODO\n !transport.options ||\n // @ts-expect-error we use undocumented stuff here TODO\n transport.options.name !== tools.appName\n ) {\n return;\n }\n\n // @ts-expect-error we use undocumented stuff here TODO\n if (transport && fs.existsSync(transport.dirname)) {\n let files;\n try {\n // @ts-expect-error we use undocumented stuff here TODO\n files = fs.readdirSync(transport.dirname);\n } catch (e) {\n console.error(`host.${hostname} Cannot read log directory: ${e.message}`);\n return;\n }\n const forXdays = new Date();\n forXdays.setDate(forXdays.getDate() - daysCount - 1); // normally winston now takes care, for old or on errors make sure fallback works a day later\n\n for (let i = 0; i < files.length; i++) {\n const match = files[i].match(/.+\\.(\\d+-\\d+-\\d+)/);\n if (match) {\n const date = new Date(match[1]);\n if (date < forXdays) {\n // delete file\n try {\n this.log({\n level: 'info',\n message: `host.${hostname} Delete log file ${files[i]}`,\n });\n console.log(`host.${hostname} Delete log file ${files[i]}`);\n // @ts-expect-error we use undocumented stuff here TODO\n fs.unlinkSync(`${transport.dirname}/${files[i]}`);\n } catch (e) {\n // there is a bug under windows, that file stays opened and cannot be deleted\n this.log({\n level: os.platform().startsWith('win') ? 'info' : 'error',\n message: `host.${hostname} Cannot delete file \"${path.normalize(\n // @ts-expect-error we use undocumented stuff here TODO\n `${transport.dirname}/${files[i]}`,\n )}\": ${e}`,\n });\n console.log(\n `host.${hostname} Cannot delete file \"${path.normalize(\n // @ts-expect-error we use undocumented stuff here TODO\n `${transport.dirname}/${files[i]}`,\n )}\": ${e.message}`,\n );\n }\n }\n }\n }\n }\n });\n }, 3_600_000); // every hour\n }\n };\n\n return log;\n}\n\nfunction getDate(): string {\n const ts = new Date();\n return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, '0')}-${ts\n .getDate()\n .toString()\n .padStart(2, '0')}`;\n}\n\nfunction timestamp(date: string): string {\n const ts = date ? new Date(date) : new Date();\n return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, '0')}-${ts\n .getDate()\n .toString()\n .padStart(2, '0')} ${ts.getHours().toString().padStart(2, '0')}:${ts\n .getMinutes()\n .toString()\n .padStart(2, '0')}:${ts.getSeconds().toString().padStart(2, '0')}.${ts\n .getMilliseconds()\n .toString()\n .padStart(3, '0')} `;\n}\n", "export const __import_meta_url =\n typeof document === 'undefined' ? new (require('url'.replace('', '')).URL)('file:' + __filename).href :\n (document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["require", "deepClone", "Transport", "winston", "os", "path", "DailyRotateFile", "fs", "files"]
|
|
7
7
|
}
|
|
@@ -28,10 +28,19 @@
|
|
|
28
28
|
|
|
29
29
|
*
|
|
30
30
|
*/
|
|
31
|
+
/** Set of password helper functions bound to a specific password */
|
|
31
32
|
export interface PasswordReturnValue {
|
|
33
|
+
/** Check whether the password fulfills the complexity requirements */
|
|
32
34
|
complexity: (password: string, callback: (isComplex: boolean) => void) => boolean;
|
|
35
|
+
/** Verify the password against the given stored hash */
|
|
33
36
|
check: (hashedPassword: string, callback: (err?: Error | null, isOk?: boolean) => void) => void;
|
|
37
|
+
/** Create a salted PBKDF2 hash of the password */
|
|
34
38
|
hash: (salt: string | null, iterations: number | null, callback: (err?: Error | null, hash?: string) => void) => void;
|
|
35
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a set of helper functions (hash, check, complexity) bound to the given password
|
|
42
|
+
*
|
|
43
|
+
* @param pw The plain text password to operate on
|
|
44
|
+
*/
|
|
36
45
|
export declare function password(pw: string): PasswordReturnValue;
|
|
37
46
|
//# sourceMappingURL=password.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/password.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n *\n * password hash and check\n *\n * 7'2014-2024 Bluefox <dogafox@gmail.com>\n * 2014 hobbyquaker <hq@ccu.io>\n *\n * derived from https://github.com/florianheinemann/password-hash-and-salt/ (MIT License)\n *\n * The created hash is of the following format: <algorithm>$<iterations>$<hash>$<salt>\n *\n * Usage Example:\n \n var password = require('./lib/password.js');\n \n password('test').hash(null, null, function (err, res) {\n console.log(res);\n \n password('test').check(res, function (err, res) {\n console.log('test: ' + res);\n });\n \n password('muh').check(res, function (err, res) {\n console.log('muh: ' + res);\n });\n \n });\n \n *\n */\n\nimport crypto from 'node:crypto';\n\nexport interface PasswordReturnValue {\n complexity: (password: string, callback: (isComplex: boolean) => void) => boolean;\n check: (hashedPassword: string, callback: (err?: Error | null, isOk?: boolean) => void) => void;\n hash: (\n salt: string | null,\n iterations: number | null,\n callback: (err?: Error | null, hash?: string) => void,\n ) => void;\n}\n\nexport function password(pw: string): PasswordReturnValue {\n return {\n hash: (salt, iterations, callback) => {\n salt = salt || crypto.randomBytes(16).toString('hex');\n iterations = iterations || 10_000;\n\n crypto.pbkdf2(pw, salt, iterations, 256, 'sha256', (err, key) => {\n if (err) {\n return callback(err);\n }\n\n callback(null, `pbkdf2$${iterations}$${key.toString('hex')}$${salt}`);\n });\n },\n check: function (hashedPassword, callback) {\n if (!hashedPassword) {\n return callback(null, false);\n }\n const key = hashedPassword.split('$');\n if (key.length !== 4 || !key[2] || !key[3]) {\n return callback(new Error('Hash not formatted correctly'));\n }\n if (key[0] !== 'pbkdf2') {\n return callback(new Error('Unknown'));\n }\n\n this.hash(key[3], parseInt(key[1], 10), (error, newHash) => {\n if (error) {\n callback(error);\n } else {\n callback(null, newHash === hashedPassword);\n }\n });\n },\n complexity: (password, callback) => {\n let result = false;\n if (typeof password === 'string') {\n result =\n password.length >= 8 && // minimum length is 8\n /\\d/.test(password) && // contains at least one digit\n /[a-z]/.test(password) && // contains at least one lower case letter\n /[A-Z]/.test(password); // contains at least one upper case letter\n }\n typeof callback === 'function' && callback(result);\n return result; // true if the complexity OK\n },\n };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AA+BA,yBAAmB;
|
|
4
|
+
"sourcesContent": ["/**\n *\n * password hash and check\n *\n * 7'2014-2024 Bluefox <dogafox@gmail.com>\n * 2014 hobbyquaker <hq@ccu.io>\n *\n * derived from https://github.com/florianheinemann/password-hash-and-salt/ (MIT License)\n *\n * The created hash is of the following format: <algorithm>$<iterations>$<hash>$<salt>\n *\n * Usage Example:\n \n var password = require('./lib/password.js');\n \n password('test').hash(null, null, function (err, res) {\n console.log(res);\n \n password('test').check(res, function (err, res) {\n console.log('test: ' + res);\n });\n \n password('muh').check(res, function (err, res) {\n console.log('muh: ' + res);\n });\n \n });\n \n *\n */\n\nimport crypto from 'node:crypto';\n\n/** Set of password helper functions bound to a specific password */\nexport interface PasswordReturnValue {\n /** Check whether the password fulfills the complexity requirements */\n complexity: (password: string, callback: (isComplex: boolean) => void) => boolean;\n /** Verify the password against the given stored hash */\n check: (hashedPassword: string, callback: (err?: Error | null, isOk?: boolean) => void) => void;\n /** Create a salted PBKDF2 hash of the password */\n hash: (\n salt: string | null,\n iterations: number | null,\n callback: (err?: Error | null, hash?: string) => void,\n ) => void;\n}\n\n/**\n * Create a set of helper functions (hash, check, complexity) bound to the given password\n *\n * @param pw The plain text password to operate on\n */\nexport function password(pw: string): PasswordReturnValue {\n return {\n hash: (salt, iterations, callback) => {\n salt = salt || crypto.randomBytes(16).toString('hex');\n iterations = iterations || 10_000;\n\n crypto.pbkdf2(pw, salt, iterations, 256, 'sha256', (err, key) => {\n if (err) {\n return callback(err);\n }\n\n callback(null, `pbkdf2$${iterations}$${key.toString('hex')}$${salt}`);\n });\n },\n check: function (hashedPassword, callback) {\n if (!hashedPassword) {\n return callback(null, false);\n }\n const key = hashedPassword.split('$');\n if (key.length !== 4 || !key[2] || !key[3]) {\n return callback(new Error('Hash not formatted correctly'));\n }\n if (key[0] !== 'pbkdf2') {\n return callback(new Error('Unknown'));\n }\n\n this.hash(key[3], parseInt(key[1], 10), (error, newHash) => {\n if (error) {\n callback(error);\n } else {\n callback(null, newHash === hashedPassword);\n }\n });\n },\n complexity: (password, callback) => {\n let result = false;\n if (typeof password === 'string') {\n result =\n password.length >= 8 && // minimum length is 8\n /\\d/.test(password) && // contains at least one digit\n /[a-z]/.test(password) && // contains at least one lower case letter\n /[A-Z]/.test(password); // contains at least one upper case letter\n }\n typeof callback === 'function' && callback(result);\n return result; // true if the complexity OK\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AA+BA,yBAAmB;AAqBb,SAAU,SAAS,IAAU;AAC/B,SAAO;IACH,MAAM,CAAC,MAAM,YAAY,aAAY;AACjC,aAAO,QAAQ,mBAAAA,QAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AACpD,mBAAa,cAAc;AAE3B,yBAAAA,QAAO,OAAO,IAAI,MAAM,YAAY,KAAK,UAAU,CAAC,KAAK,QAAO;AAC5D,YAAI,KAAK;AACL,iBAAO,SAAS,GAAG;QACvB;AAEA,iBAAS,MAAM,UAAU,UAAU,IAAI,IAAI,SAAS,KAAK,CAAC,IAAI,IAAI,EAAE;MACxE,CAAC;IACL;IACA,OAAO,SAAU,gBAAgB,UAAQ;AACrC,UAAI,CAAC,gBAAgB;AACjB,eAAO,SAAS,MAAM,KAAK;MAC/B;AACA,YAAM,MAAM,eAAe,MAAM,GAAG;AACpC,UAAI,IAAI,WAAW,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;AACxC,eAAO,SAAS,IAAI,MAAM,8BAA8B,CAAC;MAC7D;AACA,UAAI,IAAI,CAAC,MAAM,UAAU;AACrB,eAAO,SAAS,IAAI,MAAM,SAAS,CAAC;MACxC;AAEA,WAAK,KAAK,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,YAAW;AACvD,YAAI,OAAO;AACP,mBAAS,KAAK;QAClB,OAAO;AACH,mBAAS,MAAM,YAAY,cAAc;QAC7C;MACJ,CAAC;IACL;IACA,YAAY,CAACC,WAAU,aAAY;AAC/B,UAAI,SAAS;AACb,UAAI,OAAOA,cAAa,UAAU;AAC9B,iBACIA,UAAS,UAAU;QACnB,KAAK,KAAKA,SAAQ;QAClB,QAAQ,KAAKA,SAAQ;QACrB,QAAQ,KAAKA,SAAQ;MAC7B;AACA,aAAO,aAAa,cAAc,SAAS,MAAM;AACjD,aAAO;IACX;;AAER;",
|
|
6
6
|
"names": ["crypto", "password"]
|
|
7
7
|
}
|
|
@@ -25,6 +25,9 @@ function createAdapterStore(session, defaultTtl = 3600) {
|
|
|
25
25
|
const Store = session.Store;
|
|
26
26
|
class AdapterStore extends Store {
|
|
27
27
|
adapter;
|
|
28
|
+
/**
|
|
29
|
+
* @param options Store options including the adapter instance used to read and write sessions
|
|
30
|
+
*/
|
|
28
31
|
constructor(options) {
|
|
29
32
|
super(options);
|
|
30
33
|
this.adapter = options.adapter;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/common/session.ts"],
|
|
4
|
-
"sourcesContent": ["type SessionData = Record<string, any>;\n\ntype Session = {\n Store: any;\n};\n\n// TODO: in the long term move this file somewhere where we have types access it is nowhere used in controller itself and just exported for adapters so it should go to js-controller-adapter package\ninterface AdapterStoreOptions {\n /** The ioBroker adapter */\n adapter: any;\n /** The cookie */\n cookie?: {\n maxAge?: number;\n originalMaxAge?: number;\n };\n}\n\n/**\n * Function to create an AdapterStore constructor\n *\n * @param session The session object, like \"express-session\"\n * @param defaultTtl the default time to live in seconds\n * @returns the constructor to create a new AdapterStore\n */\nexport function createAdapterStore(session: Session, defaultTtl = 3600): any {\n const Store = session.Store;\n\n class AdapterStore extends Store {\n private readonly adapter: any;\n\n constructor(options: AdapterStoreOptions) {\n super(options);\n\n this.adapter = options.adapter;\n\n options = options || {};\n if (!options.cookie) {\n options.cookie = { maxAge: defaultTtl };\n }\n Store.call(this, options);\n }\n\n /**\n * Attempt to fetch session by the given `sid`.\n *\n * @param sid Session ID\n * @param fn callback\n */\n get(sid: string, fn: (err?: Error | string | null, obj?: SessionData) => void): void {\n this.adapter.getSession(sid, (obj: SessionData): void => {\n if (obj) {\n if (fn) {\n return fn(null, obj);\n }\n } else if (fn) {\n return fn();\n }\n });\n }\n\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param sess the session\n * @param fn callback\n */\n set(sid: string, sess: SessionData, fn: (err?: Error | null) => void): void;\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param ttl Time to live\n * @param sess the session\n * @param fn callback\n */\n set(sid: string, ttl: number, sess: SessionData, fn: (err?: Error | null) => void): void;\n\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param ttl Time to live\n * @param sess the session\n * @param fn callback\n */\n set(sid: unknown, ttl: unknown, sess: unknown, fn?: unknown): void {\n if (typeof sess === 'function') {\n fn = sess as (err?: Error | null) => void;\n sess = ttl;\n // analyse if the session is stored directly from express session\n ttl = (sess as SessionData)?.cookie?.originalMaxAge\n ? Math.round((sess as SessionData).cookie.originalMaxAge / 1000)\n : defaultTtl;\n }\n ttl = ttl || defaultTtl;\n this.adapter.setSession(\n sid as string,\n ttl as number,\n sess as SessionData,\n function (err?: Error | null): void {\n // @ts-expect-error fix later\n fn?.call(this, err);\n },\n ); // do not use here => !!!\n }\n\n /**\n * Destroy the session associated with the given `sid`.\n *\n * @param sid Session ID\n * @param fn callback\n */\n destroy(sid: string, fn: () => void): void {\n this.adapter.destroySession(sid, fn);\n }\n }\n\n return AdapterStore;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAiBA;;;;;AAOM,SAAU,mBAAmB,SAAkB,aAAa,MAAI;AAClE,QAAM,QAAQ,QAAQ;EAEtB,MAAM,qBAAqB,MAAK;IACX
|
|
4
|
+
"sourcesContent": ["type SessionData = Record<string, any>;\n\ntype Session = {\n Store: any;\n};\n\n// TODO: in the long term move this file somewhere where we have types access it is nowhere used in controller itself and just exported for adapters so it should go to js-controller-adapter package\ninterface AdapterStoreOptions {\n /** The ioBroker adapter */\n adapter: any;\n /** The cookie */\n cookie?: {\n maxAge?: number;\n originalMaxAge?: number;\n };\n}\n\n/**\n * Function to create an AdapterStore constructor\n *\n * @param session The session object, like \"express-session\"\n * @param defaultTtl the default time to live in seconds\n * @returns the constructor to create a new AdapterStore\n */\nexport function createAdapterStore(session: Session, defaultTtl = 3600): any {\n const Store = session.Store;\n\n class AdapterStore extends Store {\n private readonly adapter: any;\n\n /**\n * @param options Store options including the adapter instance used to read and write sessions\n */\n constructor(options: AdapterStoreOptions) {\n super(options);\n\n this.adapter = options.adapter;\n\n options = options || {};\n if (!options.cookie) {\n options.cookie = { maxAge: defaultTtl };\n }\n Store.call(this, options);\n }\n\n /**\n * Attempt to fetch session by the given `sid`.\n *\n * @param sid Session ID\n * @param fn callback\n */\n get(sid: string, fn: (err?: Error | string | null, obj?: SessionData) => void): void {\n this.adapter.getSession(sid, (obj: SessionData): void => {\n if (obj) {\n if (fn) {\n return fn(null, obj);\n }\n } else if (fn) {\n return fn();\n }\n });\n }\n\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param sess the session\n * @param fn callback\n */\n set(sid: string, sess: SessionData, fn: (err?: Error | null) => void): void;\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param ttl Time to live\n * @param sess the session\n * @param fn callback\n */\n set(sid: string, ttl: number, sess: SessionData, fn: (err?: Error | null) => void): void;\n\n /**\n * Commit the given `sess` object associated with the given `sid`.\n *\n * @param sid Session ID\n * @param ttl Time to live\n * @param sess the session\n * @param fn callback\n */\n set(sid: unknown, ttl: unknown, sess: unknown, fn?: unknown): void {\n if (typeof sess === 'function') {\n fn = sess as (err?: Error | null) => void;\n sess = ttl;\n // analyse if the session is stored directly from express session\n ttl = (sess as SessionData)?.cookie?.originalMaxAge\n ? Math.round((sess as SessionData).cookie.originalMaxAge / 1000)\n : defaultTtl;\n }\n ttl = ttl || defaultTtl;\n this.adapter.setSession(\n sid as string,\n ttl as number,\n sess as SessionData,\n function (err?: Error | null): void {\n // @ts-expect-error fix later\n fn?.call(this, err);\n },\n ); // do not use here => !!!\n }\n\n /**\n * Destroy the session associated with the given `sid`.\n *\n * @param sid Session ID\n * @param fn callback\n */\n destroy(sid: string, fn: () => void): void {\n this.adapter.destroySession(sid, fn);\n }\n }\n\n return AdapterStore;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAiBA;;;;;AAOM,SAAU,mBAAmB,SAAkB,aAAa,MAAI;AAClE,QAAM,QAAQ,QAAQ;EAEtB,MAAM,qBAAqB,MAAK;IACX;;;;IAKjB,YAAY,SAA4B;AACpC,YAAM,OAAO;AAEb,WAAK,UAAU,QAAQ;AAEvB,gBAAU,WAAW,CAAA;AACrB,UAAI,CAAC,QAAQ,QAAQ;AACjB,gBAAQ,SAAS,EAAE,QAAQ,WAAU;MACzC;AACA,YAAM,KAAK,MAAM,OAAO;IAC5B;;;;;;;IAQA,IAAI,KAAa,IAA4D;AACzE,WAAK,QAAQ,WAAW,KAAK,CAAC,QAA0B;AACpD,YAAI,KAAK;AACL,cAAI,IAAI;AACJ,mBAAO,GAAG,MAAM,GAAG;UACvB;QACJ,WAAW,IAAI;AACX,iBAAO,GAAE;QACb;MACJ,CAAC;IACL;;;;;;;;;IA4BA,IAAI,KAAc,KAAc,MAAe,IAAY;AACvD,UAAI,OAAO,SAAS,YAAY;AAC5B,aAAK;AACL,eAAO;AAEP,cAAO,MAAsB,QAAQ,iBAC/B,KAAK,MAAO,KAAqB,OAAO,iBAAiB,GAAI,IAC7D;MACV;AACA,YAAM,OAAO;AACb,WAAK,QAAQ,WACT,KACA,KACA,MACA,SAAU,KAAkB;AAExB,YAAI,KAAK,MAAM,GAAG;MACtB,CAAC;IAET;;;;;;;IAQA,QAAQ,KAAa,IAAc;AAC/B,WAAK,QAAQ,eAAe,KAAK,EAAE;IACvC;;AAGJ,SAAO;AACX;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -14,6 +14,7 @@ type DockerInformation = {
|
|
|
14
14
|
/** If it is the official Docker image */
|
|
15
15
|
isOfficial: false;
|
|
16
16
|
};
|
|
17
|
+
/** Detailed information about the host system ioBroker runs on */
|
|
17
18
|
export interface HostInfo {
|
|
18
19
|
/** Converted OS for human readability */
|
|
19
20
|
Platform: NodeJS.Platform | 'docker' | 'Windows' | 'OSX';
|
|
@@ -60,6 +61,7 @@ interface FormatAliasValueOptions {
|
|
|
60
61
|
/** Id of the target object, used for logging */
|
|
61
62
|
targetId?: string;
|
|
62
63
|
}
|
|
64
|
+
/** Information about the available ioBroker Docker image */
|
|
63
65
|
export interface DockerImageInformation {
|
|
64
66
|
/** The official version like v10.0.0 */
|
|
65
67
|
version: string;
|
|
@@ -99,6 +101,13 @@ export declare function checkNonEditable(oldObject: ioBroker.SettableObject | nu
|
|
|
99
101
|
* @param installedVersion the current installed version
|
|
100
102
|
*/
|
|
101
103
|
export declare function upToDate(repoVersion: string, installedVersion: string): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Decrypt a phrase that was encrypted with the legacy aes192 algorithm
|
|
106
|
+
*
|
|
107
|
+
* @param password The password used to derive the decryption key
|
|
108
|
+
* @param data The encrypted data to decrypt
|
|
109
|
+
* @param callback Called with the decrypted string, or null on error
|
|
110
|
+
*/
|
|
102
111
|
export declare function decryptPhrase(password: string, data: any, callback: (decrypted?: null | string) => void): void;
|
|
103
112
|
/**
|
|
104
113
|
* Checks if multiple host objects exists, without using object views
|
|
@@ -155,11 +164,18 @@ export declare function createUuid(objects: any): Promise<void | string>;
|
|
|
155
164
|
/**
|
|
156
165
|
* Download file to tmp or return file name directly
|
|
157
166
|
*
|
|
158
|
-
* @param urlOrPath
|
|
159
|
-
* @param fileName
|
|
160
|
-
* @param callback
|
|
167
|
+
* @param urlOrPath URL to download from, or a local file path
|
|
168
|
+
* @param fileName Target file name used when the source is downloaded to the tmp directory
|
|
169
|
+
* @param callback Called with the path to the local file
|
|
161
170
|
*/
|
|
162
171
|
export declare function getFile(urlOrPath: string, fileName: string, callback: (file?: string) => void): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Return the content of a JSON file, downloading it from a URL or reading it directly from disk
|
|
174
|
+
*
|
|
175
|
+
* @param urlOrPath URL to download the JSON from, or a local file path
|
|
176
|
+
* @param agent User agent string used for the download request
|
|
177
|
+
* @param callback Called with the parsed sources and the resolved url/path
|
|
178
|
+
*/
|
|
163
179
|
export declare function getJson(urlOrPath: string, agent: string, callback: (sources?: Record<string, any> | null, urlOrPath?: string | null) => void): Promise<void>;
|
|
164
180
|
/**
|
|
165
181
|
* Return content of the json file. Download it or read directly
|
|
@@ -182,6 +198,7 @@ interface Multilingual {
|
|
|
182
198
|
uk?: string;
|
|
183
199
|
'zh-cn'?: string;
|
|
184
200
|
}
|
|
201
|
+
/** Information about an installed adapter */
|
|
185
202
|
export interface AdapterInformation {
|
|
186
203
|
/** this flag is only true for the js-controller */
|
|
187
204
|
controller: boolean;
|
|
@@ -262,9 +279,13 @@ export declare function getAdapterDir(adapter: string): string | null;
|
|
|
262
279
|
* Returns the hostname of this host
|
|
263
280
|
*/
|
|
264
281
|
export declare function getHostName(): string;
|
|
282
|
+
/** Options for installing a node module */
|
|
265
283
|
export interface InstallNodeModuleOptions {
|
|
284
|
+
/** Whether the `--unsafe-perm` flag should be used */
|
|
266
285
|
unsafePerm?: boolean;
|
|
286
|
+
/** Whether to include `stderr` in the output and increase the loglevel to include more than errors */
|
|
267
287
|
debug?: boolean;
|
|
288
|
+
/** Which directory to work in. If none is given, this defaults to ioBroker's root directory. */
|
|
268
289
|
cwd?: string;
|
|
269
290
|
}
|
|
270
291
|
/**
|
|
@@ -281,8 +302,11 @@ export declare function detectPackageManagerWithFallback(cwd?: string): Promise<
|
|
|
281
302
|
* @param options Options for the installation
|
|
282
303
|
*/
|
|
283
304
|
export declare function installNodeModule(npmUrl: string, options?: InstallNodeModuleOptions): Promise<CommandResult>;
|
|
305
|
+
/** Options for uninstalling a node module */
|
|
284
306
|
export interface UninstallNodeModuleOptions {
|
|
307
|
+
/** Whether to include `stderr` in the output and increase the loglevel to include more than errors */
|
|
285
308
|
debug?: boolean;
|
|
309
|
+
/** Which directory to work in. If none is given, this defaults to ioBroker's root directory. */
|
|
286
310
|
cwd?: string;
|
|
287
311
|
}
|
|
288
312
|
/**
|
|
@@ -292,9 +316,13 @@ export interface UninstallNodeModuleOptions {
|
|
|
292
316
|
* @param options Options for the installation
|
|
293
317
|
*/
|
|
294
318
|
export declare function uninstallNodeModule(packageName: string, options?: UninstallNodeModuleOptions): Promise<CommandResult>;
|
|
319
|
+
/** Options for rebuilding native node modules */
|
|
295
320
|
export interface RebuildNodeModulesOptions {
|
|
321
|
+
/** Whether to include `stderr` in the output and increase the loglevel to include more than errors */
|
|
296
322
|
debug?: boolean;
|
|
323
|
+
/** Which directory to work in. If none is given, this defaults to ioBroker's root directory. */
|
|
297
324
|
cwd?: string;
|
|
325
|
+
/** module which should be rebuilt */
|
|
298
326
|
module?: string;
|
|
299
327
|
}
|
|
300
328
|
/**
|
|
@@ -304,15 +332,20 @@ export interface RebuildNodeModulesOptions {
|
|
|
304
332
|
* @param options Options for the rebuild
|
|
305
333
|
*/
|
|
306
334
|
export declare function rebuildNodeModules(options?: RebuildNodeModulesOptions): Promise<CommandResult>;
|
|
335
|
+
/** Information about the disk on which ioBroker is installed */
|
|
307
336
|
export interface GetDiskInfoResponse {
|
|
337
|
+
/** Total size of the disk in bytes */
|
|
308
338
|
'Disk size': number;
|
|
339
|
+
/** Free space on the disk in bytes */
|
|
309
340
|
'Disk free': number;
|
|
310
341
|
}
|
|
311
342
|
/**
|
|
312
343
|
* Read disk free space
|
|
313
344
|
*/
|
|
314
345
|
export declare function getDiskInfo(): Promise<GetDiskInfoResponse | null>;
|
|
346
|
+
/** Parsed information about an SSL/TLS certificate */
|
|
315
347
|
export interface CertificateInfo {
|
|
348
|
+
/** path to the certificate file, or null if the certificate was passed directly */
|
|
316
349
|
certificateFilename: string | null;
|
|
317
350
|
/** the certificate itself */
|
|
318
351
|
certificate: string;
|
|
@@ -328,7 +361,9 @@ export interface CertificateInfo {
|
|
|
328
361
|
subject: Record<string, any>;
|
|
329
362
|
/** server name this certificate belong to */
|
|
330
363
|
dnsNames: {
|
|
364
|
+
/** Type of the subject alternative name entry */
|
|
331
365
|
type: number;
|
|
366
|
+
/** Value of the subject alternative name entry */
|
|
332
367
|
value: string;
|
|
333
368
|
}[];
|
|
334
369
|
/** this certificate can be used for the following purposes */
|
|
@@ -343,12 +378,15 @@ export interface CertificateInfo {
|
|
|
343
378
|
/**
|
|
344
379
|
* Returns information about a certificate
|
|
345
380
|
*
|
|
346
|
-
* @param cert
|
|
381
|
+
* @param cert The certificate as a PEM string, or a path to the certificate file
|
|
347
382
|
* @returns certificate information object
|
|
348
383
|
*/
|
|
349
384
|
export declare function getCertificateInfo(cert: string): null | CertificateInfo;
|
|
385
|
+
/** Default self-signed certificates shipped with the controller */
|
|
350
386
|
export interface DefaultCertificates {
|
|
387
|
+
/** PEM encoded default private key */
|
|
351
388
|
defaultPrivate: string;
|
|
389
|
+
/** PEM encoded default public certificate */
|
|
352
390
|
defaultPublic: string;
|
|
353
391
|
}
|
|
354
392
|
/** Maximum time after which cert has to expire - 365 days in ms */
|
|
@@ -418,6 +456,14 @@ export declare function promisify(fn: (...args: any[]) => void, context?: any, r
|
|
|
418
456
|
* Otherwise, the Promise will resolve with an array
|
|
419
457
|
*/
|
|
420
458
|
export declare function promisifyNoError(fn: (...args: any[]) => void, context?: any, returnArgNames?: string[]): (...args: any[]) => Promise<any>;
|
|
459
|
+
/**
|
|
460
|
+
* Set the given quality code on all states belonging to an instance
|
|
461
|
+
*
|
|
462
|
+
* @param objects The objects database client
|
|
463
|
+
* @param states The states database client
|
|
464
|
+
* @param namespace The instance namespace whose states should be updated (e.g. "admin.0")
|
|
465
|
+
* @param q The quality code to assign to each state
|
|
466
|
+
*/
|
|
421
467
|
export declare function setQualityForInstance(objects: any, states: any, namespace: string, q: number): Promise<void>;
|
|
422
468
|
/**
|
|
423
469
|
* Converts ioB pattern into regex.
|
|
@@ -428,8 +474,7 @@ export declare function pattern2RegEx(pattern: string): string;
|
|
|
428
474
|
/**
|
|
429
475
|
* Checks if a pattern is valid
|
|
430
476
|
*
|
|
431
|
-
* @param pattern
|
|
432
|
-
* @pattern pattern to check for validity
|
|
477
|
+
* @param pattern The pattern to check for validity
|
|
433
478
|
*/
|
|
434
479
|
export declare function isValidPattern(pattern: string): boolean;
|
|
435
480
|
/**
|
|
@@ -476,7 +521,7 @@ export declare function measureEventLoopLag(ms: number, cb: (eventLoopLag?: numb
|
|
|
476
521
|
* This function convert state values by read and write of aliases. Function is synchronous.
|
|
477
522
|
* On errors, null is returned instead
|
|
478
523
|
*
|
|
479
|
-
* @param options
|
|
524
|
+
* @param options Source and target common/id definitions, the state to convert and a logger
|
|
480
525
|
*/
|
|
481
526
|
export declare function formatAliasValue(options: FormatAliasValueOptions): ioBroker.State | null;
|
|
482
527
|
/**
|
|
@@ -559,7 +604,7 @@ export declare function resolveAdapterMainFile(adapter: string): Promise<string>
|
|
|
559
604
|
/**
|
|
560
605
|
* Returns the default nodeArgs required to execute the main file, e.g., transpile hooks for TypeScript
|
|
561
606
|
*
|
|
562
|
-
* @param mainFile
|
|
607
|
+
* @param mainFile Path to the adapter main file that will be executed
|
|
563
608
|
* @returns default node args for cli
|
|
564
609
|
*/
|
|
565
610
|
export declare function getDefaultNodeArgs(mainFile: string): string[];
|
|
@@ -575,9 +620,13 @@ export declare function getDefaultRequireResolvePaths(callerModule: NodeModule):
|
|
|
575
620
|
* @param url The URL to parse
|
|
576
621
|
*/
|
|
577
622
|
export declare function isShortGithubUrl(url: string): boolean;
|
|
623
|
+
/** A short GitHub URL parsed into its separate parts */
|
|
578
624
|
export interface ParsedGithubUrl {
|
|
625
|
+
/** GitHub user or organization name */
|
|
579
626
|
user: string;
|
|
627
|
+
/** Repository name */
|
|
580
628
|
repo: string;
|
|
629
|
+
/** Optional commit-ish (branch, tag or commit hash) */
|
|
581
630
|
commit?: string;
|
|
582
631
|
}
|
|
583
632
|
/**
|
|
@@ -614,6 +663,11 @@ export declare function removePreservedProperties(preserve: Record<string, any>,
|
|
|
614
663
|
*/
|
|
615
664
|
export declare function getInstanceIndicatorObjects(namespace: string, adapterCommon: ioBroker.AdapterCommon): ioBroker.StateObject[];
|
|
616
665
|
export type InternalLogger = Omit<ioBroker.Logger, 'level'>;
|
|
666
|
+
/**
|
|
667
|
+
* Normalize a logger-like object into a complete logger, filling missing log level methods with no-ops
|
|
668
|
+
*
|
|
669
|
+
* @param log A logger or partial logger object; if falsy, a no-op logger is created
|
|
670
|
+
*/
|
|
617
671
|
export declare function getLogger(log: any): InternalLogger;
|
|
618
672
|
/**
|
|
619
673
|
* Set capabilities of the given executable on Linux systems
|
|
@@ -635,7 +689,9 @@ export declare function setExecutableCapabilities(execPath: string, capabilities
|
|
|
635
689
|
* @returns array of all licenses stored on iobroker.net
|
|
636
690
|
*/
|
|
637
691
|
export declare function updateLicenses(objects: any, login: string, password: string): Promise<any[]>;
|
|
692
|
+
/** Options for compressing a file with GZip */
|
|
638
693
|
export interface GZipFileOptions {
|
|
694
|
+
/** Delete the input file after compression. Default: false. */
|
|
639
695
|
deleteInput?: boolean;
|
|
640
696
|
}
|
|
641
697
|
/**
|
|
@@ -646,6 +702,7 @@ export interface GZipFileOptions {
|
|
|
646
702
|
* @param options Options for the compression
|
|
647
703
|
*/
|
|
648
704
|
export declare function compressFileGZip(inputFilename: string, outputFilename: string, options?: GZipFileOptions): Promise<void>;
|
|
705
|
+
/** Result of validating a configured data directory */
|
|
649
706
|
export interface DataDirValidation {
|
|
650
707
|
/** if data directory is valid */
|
|
651
708
|
valid: boolean;
|