dbdock 1.1.3 → 1.1.4
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/README.md +118 -25
- package/dist/backup/backup.service.js +7 -6
- package/dist/backup/backup.service.js.map +1 -1
- package/dist/cli/commands/init.js +126 -21
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/migrate-config.d.ts +1 -0
- package/dist/cli/commands/migrate-config.js +172 -0
- package/dist/cli/commands/migrate-config.js.map +1 -0
- package/dist/cli/commands/restore.js +1 -1
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/config.schema.d.ts +5 -1
- package/dist/config/config.schema.js +25 -0
- package/dist/config/config.schema.js.map +1 -1
- package/dist/config/config.service.d.ts +2 -0
- package/dist/config/config.service.js +59 -5
- package/dist/config/config.service.js.map +1 -1
- package/dist/config/permissions.checker.d.ts +10 -0
- package/dist/config/permissions.checker.js +137 -0
- package/dist/config/permissions.checker.js.map +1 -0
- package/dist/config/pgpass.helper.d.ts +15 -0
- package/dist/config/pgpass.helper.js +184 -0
- package/dist/config/pgpass.helper.js.map +1 -0
- package/dist/config/secrets.validator.d.ts +17 -0
- package/dist/config/secrets.validator.js +169 -0
- package/dist/config/secrets.validator.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +35 -0
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.checkFilePermissions = checkFilePermissions;
|
|
37
|
+
exports.isFileWorldReadable = isFileWorldReadable;
|
|
38
|
+
exports.suggestPermissionsFix = suggestPermissionsFix;
|
|
39
|
+
exports.checkDirectoryPermissions = checkDirectoryPermissions;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
function checkFilePermissions(filePath) {
|
|
44
|
+
if (os.platform() === 'win32') {
|
|
45
|
+
return {
|
|
46
|
+
secure: true,
|
|
47
|
+
currentMode: 'N/A (Windows)',
|
|
48
|
+
recommendedMode: 'N/A (Windows)',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const stats = fs.statSync(filePath);
|
|
53
|
+
const mode = stats.mode;
|
|
54
|
+
const ownerRead = (mode & 0o400) !== 0;
|
|
55
|
+
const ownerWrite = (mode & 0o200) !== 0;
|
|
56
|
+
const groupRead = (mode & 0o040) !== 0;
|
|
57
|
+
const groupWrite = (mode & 0o020) !== 0;
|
|
58
|
+
const otherRead = (mode & 0o004) !== 0;
|
|
59
|
+
const otherWrite = (mode & 0o002) !== 0;
|
|
60
|
+
const modeString = (mode & 0o777).toString(8).padStart(3, '0');
|
|
61
|
+
const isWorldReadable = otherRead;
|
|
62
|
+
const isGroupReadable = groupRead;
|
|
63
|
+
const hasWriteByOthers = otherWrite || groupWrite;
|
|
64
|
+
const secure = !isWorldReadable && !hasWriteByOthers;
|
|
65
|
+
let warning;
|
|
66
|
+
if (isWorldReadable) {
|
|
67
|
+
warning = 'Config file is world-readable. Anyone on this system can read your secrets.';
|
|
68
|
+
}
|
|
69
|
+
else if (hasWriteByOthers) {
|
|
70
|
+
warning = 'Config file is writable by group or others. This could allow unauthorized modifications.';
|
|
71
|
+
}
|
|
72
|
+
else if (isGroupReadable) {
|
|
73
|
+
warning = 'Config file is readable by group members.';
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
secure,
|
|
77
|
+
currentMode: modeString,
|
|
78
|
+
recommendedMode: '600',
|
|
79
|
+
warning,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return {
|
|
84
|
+
secure: true,
|
|
85
|
+
currentMode: 'unknown',
|
|
86
|
+
recommendedMode: '600',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function isFileWorldReadable(filePath) {
|
|
91
|
+
if (os.platform() === 'win32') {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const stats = fs.statSync(filePath);
|
|
96
|
+
return (stats.mode & 0o004) !== 0;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function suggestPermissionsFix(filePath) {
|
|
103
|
+
const absolutePath = path.resolve(filePath);
|
|
104
|
+
return `chmod 600 "${absolutePath}"`;
|
|
105
|
+
}
|
|
106
|
+
function checkDirectoryPermissions(dirPath) {
|
|
107
|
+
if (os.platform() === 'win32') {
|
|
108
|
+
return {
|
|
109
|
+
secure: true,
|
|
110
|
+
currentMode: 'N/A (Windows)',
|
|
111
|
+
recommendedMode: 'N/A (Windows)',
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const stats = fs.statSync(dirPath);
|
|
116
|
+
const mode = stats.mode;
|
|
117
|
+
const modeString = (mode & 0o777).toString(8).padStart(3, '0');
|
|
118
|
+
const otherRead = (mode & 0o004) !== 0;
|
|
119
|
+
const otherWrite = (mode & 0o002) !== 0;
|
|
120
|
+
const otherExecute = (mode & 0o001) !== 0;
|
|
121
|
+
const secure = !otherWrite;
|
|
122
|
+
return {
|
|
123
|
+
secure,
|
|
124
|
+
currentMode: modeString,
|
|
125
|
+
recommendedMode: '700',
|
|
126
|
+
warning: otherWrite ? 'Directory is writable by others' : undefined,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return {
|
|
131
|
+
secure: true,
|
|
132
|
+
currentMode: 'unknown',
|
|
133
|
+
recommendedMode: '700',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=permissions.checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.checker.js","sourceRoot":"","sources":["../../src/config/permissions.checker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,oDAkDC;AAED,kDAWC;AAED,sDAGC;AAED,8DAkCC;AAnHD,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AASzB,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,eAAe;YAC5B,eAAe,EAAE,eAAe;SACjC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QAExB,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAExC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE/D,MAAM,eAAe,GAAG,SAAS,CAAC;QAClC,MAAM,eAAe,GAAG,SAAS,CAAC;QAClC,MAAM,gBAAgB,GAAG,UAAU,IAAI,UAAU,CAAC;QAElD,MAAM,MAAM,GAAG,CAAC,eAAe,IAAI,CAAC,gBAAgB,CAAC;QAErD,IAAI,OAA2B,CAAC;QAChC,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,GAAG,6EAA6E,CAAC;QAC1F,CAAC;aAAM,IAAI,gBAAgB,EAAE,CAAC;YAC5B,OAAO,GAAG,0FAA0F,CAAC;QACvG,CAAC;aAAM,IAAI,eAAe,EAAE,CAAC;YAC3B,OAAO,GAAG,2CAA2C,CAAC;QACxD,CAAC;QAED,OAAO;YACL,MAAM;YACN,WAAW,EAAE,UAAU;YACvB,eAAe,EAAE,KAAK;YACtB,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,SAAS;YACtB,eAAe,EAAE,KAAK;SACvB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,QAAgB;IAClD,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAgB,qBAAqB,CAAC,QAAgB;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,cAAc,YAAY,GAAG,CAAC;AACvC,CAAC;AAED,SAAgB,yBAAyB,CAAC,OAAe;IACvD,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,eAAe;YAC5B,eAAe,EAAE,eAAe;SACjC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QAExB,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAE/D,MAAM,SAAS,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,YAAY,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAE1C,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC;QAE3B,OAAO;YACL,MAAM;YACN,WAAW,EAAE,UAAU;YACvB,eAAe,EAAE,KAAK;YACtB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,SAAS;SACpE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,SAAS;YACtB,eAAe,EAAE,KAAK;SACvB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PgPassEntry {
|
|
2
|
+
hostname: string;
|
|
3
|
+
port: string;
|
|
4
|
+
database: string;
|
|
5
|
+
username: string;
|
|
6
|
+
password: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function getPgPassPath(): string;
|
|
9
|
+
export declare function checkPgPassPermissions(): boolean;
|
|
10
|
+
export declare function parsePgPassLine(line: string): PgPassEntry | null;
|
|
11
|
+
export declare function findPgPassEntry(host: string, port: number, database: string, user: string): string | null;
|
|
12
|
+
export declare function hasPgPassEntry(host: string, port: number, database: string, user: string): boolean;
|
|
13
|
+
export declare function createPgPassEntry(host: string, port: number, database: string, user: string, password: string): string;
|
|
14
|
+
export declare function appendToPgPass(entry: string): void;
|
|
15
|
+
export declare function getPgPassInstructions(host: string, port: number, database: string, user: string): string;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getPgPassPath = getPgPassPath;
|
|
37
|
+
exports.checkPgPassPermissions = checkPgPassPermissions;
|
|
38
|
+
exports.parsePgPassLine = parsePgPassLine;
|
|
39
|
+
exports.findPgPassEntry = findPgPassEntry;
|
|
40
|
+
exports.hasPgPassEntry = hasPgPassEntry;
|
|
41
|
+
exports.createPgPassEntry = createPgPassEntry;
|
|
42
|
+
exports.appendToPgPass = appendToPgPass;
|
|
43
|
+
exports.getPgPassInstructions = getPgPassInstructions;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
function getPgPassPath() {
|
|
48
|
+
if (os.platform() === 'win32') {
|
|
49
|
+
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
50
|
+
return path.join(appData, 'postgresql', 'pgpass.conf');
|
|
51
|
+
}
|
|
52
|
+
return path.join(os.homedir(), '.pgpass');
|
|
53
|
+
}
|
|
54
|
+
function checkPgPassPermissions() {
|
|
55
|
+
if (os.platform() === 'win32') {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const pgpassPath = getPgPassPath();
|
|
59
|
+
try {
|
|
60
|
+
const stats = fs.statSync(pgpassPath);
|
|
61
|
+
const mode = stats.mode & 0o777;
|
|
62
|
+
return mode === 0o600;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function parsePgPassLine(line) {
|
|
69
|
+
const trimmed = line.trim();
|
|
70
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const parts = [];
|
|
74
|
+
let current = '';
|
|
75
|
+
let escaped = false;
|
|
76
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
77
|
+
const char = trimmed[i];
|
|
78
|
+
if (escaped) {
|
|
79
|
+
current += char;
|
|
80
|
+
escaped = false;
|
|
81
|
+
}
|
|
82
|
+
else if (char === '\\') {
|
|
83
|
+
escaped = true;
|
|
84
|
+
}
|
|
85
|
+
else if (char === ':') {
|
|
86
|
+
parts.push(current);
|
|
87
|
+
current = '';
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
current += char;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
parts.push(current);
|
|
94
|
+
if (parts.length !== 5) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
hostname: parts[0],
|
|
99
|
+
port: parts[1],
|
|
100
|
+
database: parts[2],
|
|
101
|
+
username: parts[3],
|
|
102
|
+
password: parts[4],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function matchesPattern(value, pattern) {
|
|
106
|
+
if (pattern === '*') {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return value === pattern;
|
|
110
|
+
}
|
|
111
|
+
function findPgPassEntry(host, port, database, user) {
|
|
112
|
+
const pgpassPath = getPgPassPath();
|
|
113
|
+
if (!fs.existsSync(pgpassPath)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
if (!checkPgPassPermissions()) {
|
|
117
|
+
console.warn(`Warning: .pgpass file permissions too open. ` +
|
|
118
|
+
`Run "chmod 600 ${pgpassPath}" to fix.`);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const content = fs.readFileSync(pgpassPath, 'utf-8');
|
|
123
|
+
const lines = content.split('\n');
|
|
124
|
+
for (const line of lines) {
|
|
125
|
+
const entry = parsePgPassLine(line);
|
|
126
|
+
if (!entry)
|
|
127
|
+
continue;
|
|
128
|
+
const hostMatches = matchesPattern(host, entry.hostname);
|
|
129
|
+
const portMatches = matchesPattern(String(port), entry.port);
|
|
130
|
+
const dbMatches = matchesPattern(database, entry.database);
|
|
131
|
+
const userMatches = matchesPattern(user, entry.username);
|
|
132
|
+
if (hostMatches && portMatches && dbMatches && userMatches) {
|
|
133
|
+
return entry.password;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
function hasPgPassEntry(host, port, database, user) {
|
|
143
|
+
return findPgPassEntry(host, port, database, user) !== null;
|
|
144
|
+
}
|
|
145
|
+
function createPgPassEntry(host, port, database, user, password) {
|
|
146
|
+
const escape = (s) => s.replace(/\\/g, '\\\\').replace(/:/g, '\\:');
|
|
147
|
+
return `${escape(host)}:${port}:${escape(database)}:${escape(user)}:${escape(password)}`;
|
|
148
|
+
}
|
|
149
|
+
function appendToPgPass(entry) {
|
|
150
|
+
const pgpassPath = getPgPassPath();
|
|
151
|
+
const dir = path.dirname(pgpassPath);
|
|
152
|
+
if (!fs.existsSync(dir)) {
|
|
153
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
154
|
+
}
|
|
155
|
+
let existingContent = '';
|
|
156
|
+
if (fs.existsSync(pgpassPath)) {
|
|
157
|
+
existingContent = fs.readFileSync(pgpassPath, 'utf-8');
|
|
158
|
+
if (!existingContent.endsWith('\n')) {
|
|
159
|
+
existingContent += '\n';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
fs.writeFileSync(pgpassPath, existingContent + entry + '\n', { mode: 0o600 });
|
|
163
|
+
}
|
|
164
|
+
function getPgPassInstructions(host, port, database, user) {
|
|
165
|
+
const pgpassPath = getPgPassPath();
|
|
166
|
+
const entry = `${host}:${port}:${database}:${user}:YOUR_PASSWORD`;
|
|
167
|
+
return `
|
|
168
|
+
To use .pgpass for secure password storage:
|
|
169
|
+
|
|
170
|
+
1. Add this line to ${pgpassPath}:
|
|
171
|
+
${entry}
|
|
172
|
+
|
|
173
|
+
2. Set proper permissions (Unix/Mac):
|
|
174
|
+
chmod 600 ${pgpassPath}
|
|
175
|
+
|
|
176
|
+
3. Remove the password from your dbdock.config.json
|
|
177
|
+
|
|
178
|
+
Benefits:
|
|
179
|
+
- Password not exposed via PGPASSWORD environment variable
|
|
180
|
+
- Secure file permissions prevent unauthorized access
|
|
181
|
+
- Works with all PostgreSQL tools (psql, pg_dump, etc.)
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=pgpass.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgpass.helper.js","sourceRoot":"","sources":["../../src/config/pgpass.helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const SENSITIVE_FIELDS: readonly ["postgres.password", "storage.accessKeyId", "storage.secretAccessKey", "storage.cloudinaryApiKey", "storage.cloudinaryApiSecret", "encryption.secret", "alerts.smtpUser", "alerts.smtpPass", "alerts.slackWebhook"];
|
|
2
|
+
export declare const ENV_VAR_MAPPING: Record<string, string>;
|
|
3
|
+
export type SensitiveField = (typeof SENSITIVE_FIELDS)[number];
|
|
4
|
+
export declare function maskSecretValue(value: string | undefined): string;
|
|
5
|
+
export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
|
|
6
|
+
export declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
7
|
+
export declare function hasSecretsInConfig(config: Record<string, unknown>): string[];
|
|
8
|
+
export declare function loadSecretsFromEnv(): Record<string, string | undefined>;
|
|
9
|
+
export declare function mergeSecretsIntoConfig(config: Record<string, unknown>, secrets: Record<string, string | undefined>): Record<string, unknown>;
|
|
10
|
+
export interface SecretsValidationResult {
|
|
11
|
+
valid: boolean;
|
|
12
|
+
missingSecrets: string[];
|
|
13
|
+
warnings: string[];
|
|
14
|
+
mode: 'strict' | 'legacy';
|
|
15
|
+
}
|
|
16
|
+
export declare function validateSecrets(config: Record<string, unknown>, requireEnvOnly?: boolean): SecretsValidationResult;
|
|
17
|
+
export declare function formatMigrationInstructions(secretsInConfig: string[]): string;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ENV_VAR_MAPPING = exports.SENSITIVE_FIELDS = void 0;
|
|
4
|
+
exports.maskSecretValue = maskSecretValue;
|
|
5
|
+
exports.getNestedValue = getNestedValue;
|
|
6
|
+
exports.setNestedValue = setNestedValue;
|
|
7
|
+
exports.hasSecretsInConfig = hasSecretsInConfig;
|
|
8
|
+
exports.loadSecretsFromEnv = loadSecretsFromEnv;
|
|
9
|
+
exports.mergeSecretsIntoConfig = mergeSecretsIntoConfig;
|
|
10
|
+
exports.validateSecrets = validateSecrets;
|
|
11
|
+
exports.formatMigrationInstructions = formatMigrationInstructions;
|
|
12
|
+
exports.SENSITIVE_FIELDS = [
|
|
13
|
+
'postgres.password',
|
|
14
|
+
'storage.accessKeyId',
|
|
15
|
+
'storage.secretAccessKey',
|
|
16
|
+
'storage.cloudinaryApiKey',
|
|
17
|
+
'storage.cloudinaryApiSecret',
|
|
18
|
+
'encryption.secret',
|
|
19
|
+
'alerts.smtpUser',
|
|
20
|
+
'alerts.smtpPass',
|
|
21
|
+
'alerts.slackWebhook',
|
|
22
|
+
];
|
|
23
|
+
exports.ENV_VAR_MAPPING = {
|
|
24
|
+
'postgres.password': 'DBDOCK_DB_PASSWORD',
|
|
25
|
+
'storage.accessKeyId': 'DBDOCK_STORAGE_ACCESS_KEY',
|
|
26
|
+
'storage.secretAccessKey': 'DBDOCK_STORAGE_SECRET_KEY',
|
|
27
|
+
'storage.cloudinaryApiKey': 'DBDOCK_CLOUDINARY_API_KEY',
|
|
28
|
+
'storage.cloudinaryApiSecret': 'DBDOCK_CLOUDINARY_API_SECRET',
|
|
29
|
+
'encryption.secret': 'DBDOCK_ENCRYPTION_SECRET',
|
|
30
|
+
'alerts.smtpUser': 'DBDOCK_SMTP_USER',
|
|
31
|
+
'alerts.smtpPass': 'DBDOCK_SMTP_PASS',
|
|
32
|
+
'alerts.slackWebhook': 'DBDOCK_SLACK_WEBHOOK',
|
|
33
|
+
};
|
|
34
|
+
function maskSecretValue(value) {
|
|
35
|
+
if (!value)
|
|
36
|
+
return '********';
|
|
37
|
+
if (value.length <= 4)
|
|
38
|
+
return '****';
|
|
39
|
+
return value.slice(0, 2) + '****' + value.slice(-2);
|
|
40
|
+
}
|
|
41
|
+
function getNestedValue(obj, path) {
|
|
42
|
+
const keys = path.split('.');
|
|
43
|
+
let current = obj;
|
|
44
|
+
for (const key of keys) {
|
|
45
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
current = current[key];
|
|
49
|
+
}
|
|
50
|
+
return current;
|
|
51
|
+
}
|
|
52
|
+
function setNestedValue(obj, path, value) {
|
|
53
|
+
const keys = path.split('.');
|
|
54
|
+
let current = obj;
|
|
55
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
56
|
+
const key = keys[i];
|
|
57
|
+
if (!(key in current) || typeof current[key] !== 'object') {
|
|
58
|
+
current[key] = {};
|
|
59
|
+
}
|
|
60
|
+
current = current[key];
|
|
61
|
+
}
|
|
62
|
+
current[keys[keys.length - 1]] = value;
|
|
63
|
+
}
|
|
64
|
+
function hasSecretsInConfig(config) {
|
|
65
|
+
const foundSecrets = [];
|
|
66
|
+
for (const field of exports.SENSITIVE_FIELDS) {
|
|
67
|
+
const value = getNestedValue(config, field);
|
|
68
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
69
|
+
foundSecrets.push(field);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return foundSecrets;
|
|
73
|
+
}
|
|
74
|
+
function loadSecretsFromEnv() {
|
|
75
|
+
const secrets = {};
|
|
76
|
+
for (const [fieldPath, envVar] of Object.entries(exports.ENV_VAR_MAPPING)) {
|
|
77
|
+
const value = process.env[envVar];
|
|
78
|
+
if (value !== undefined && value !== '') {
|
|
79
|
+
secrets[fieldPath] = value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return secrets;
|
|
83
|
+
}
|
|
84
|
+
function mergeSecretsIntoConfig(config, secrets) {
|
|
85
|
+
const merged = JSON.parse(JSON.stringify(config));
|
|
86
|
+
for (const [fieldPath, value] of Object.entries(secrets)) {
|
|
87
|
+
if (value !== undefined) {
|
|
88
|
+
setNestedValue(merged, fieldPath, value);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return merged;
|
|
92
|
+
}
|
|
93
|
+
function validateSecrets(config, requireEnvOnly = false) {
|
|
94
|
+
const result = {
|
|
95
|
+
valid: true,
|
|
96
|
+
missingSecrets: [],
|
|
97
|
+
warnings: [],
|
|
98
|
+
mode: requireEnvOnly ? 'strict' : 'legacy',
|
|
99
|
+
};
|
|
100
|
+
const secretsInConfig = hasSecretsInConfig(config);
|
|
101
|
+
const envSecrets = loadSecretsFromEnv();
|
|
102
|
+
if (requireEnvOnly && secretsInConfig.length > 0) {
|
|
103
|
+
result.valid = false;
|
|
104
|
+
result.warnings.push('Strict mode enabled: secrets must be provided via environment variables only.');
|
|
105
|
+
for (const field of secretsInConfig) {
|
|
106
|
+
const envVar = exports.ENV_VAR_MAPPING[field];
|
|
107
|
+
result.warnings.push(` - ${field} found in config, use ${envVar} instead`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (secretsInConfig.length > 0) {
|
|
111
|
+
result.warnings.push('⚠️ Security Warning: Secrets detected in configuration file.');
|
|
112
|
+
result.warnings.push(' Consider moving them to environment variables for better security:');
|
|
113
|
+
for (const field of secretsInConfig) {
|
|
114
|
+
const envVar = exports.ENV_VAR_MAPPING[field];
|
|
115
|
+
result.warnings.push(` - ${field} → ${envVar}`);
|
|
116
|
+
}
|
|
117
|
+
result.warnings.push('');
|
|
118
|
+
result.warnings.push(' Run "npx dbdock migrate-config" to migrate automatically.');
|
|
119
|
+
}
|
|
120
|
+
const requiredSecrets = getRequiredSecrets(config);
|
|
121
|
+
for (const field of requiredSecrets) {
|
|
122
|
+
const configValue = getNestedValue(config, field);
|
|
123
|
+
const envValue = envSecrets[field];
|
|
124
|
+
if (!configValue && !envValue) {
|
|
125
|
+
result.valid = false;
|
|
126
|
+
const envVar = exports.ENV_VAR_MAPPING[field];
|
|
127
|
+
result.missingSecrets.push(`${field} (set via ${envVar})`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
function getRequiredSecrets(config) {
|
|
133
|
+
const required = [];
|
|
134
|
+
required.push('postgres.password');
|
|
135
|
+
const storageProvider = getNestedValue(config, 'storage.provider');
|
|
136
|
+
if (storageProvider === 's3' || storageProvider === 'r2') {
|
|
137
|
+
required.push('storage.accessKeyId');
|
|
138
|
+
required.push('storage.secretAccessKey');
|
|
139
|
+
}
|
|
140
|
+
else if (storageProvider === 'cloudinary') {
|
|
141
|
+
required.push('storage.cloudinaryApiKey');
|
|
142
|
+
required.push('storage.cloudinaryApiSecret');
|
|
143
|
+
}
|
|
144
|
+
const encryptionEnabled = getNestedValue(config, 'encryption.enabled');
|
|
145
|
+
if (encryptionEnabled) {
|
|
146
|
+
required.push('encryption.secret');
|
|
147
|
+
}
|
|
148
|
+
return required;
|
|
149
|
+
}
|
|
150
|
+
function formatMigrationInstructions(secretsInConfig) {
|
|
151
|
+
const lines = [
|
|
152
|
+
'',
|
|
153
|
+
'╔════════════════════════════════════════════════════════════════╗',
|
|
154
|
+
'║ SECURITY RECOMMENDATION ║',
|
|
155
|
+
'╠════════════════════════════════════════════════════════════════╣',
|
|
156
|
+
'║ Move these secrets from config file to environment variables: ║',
|
|
157
|
+
'╠════════════════════════════════════════════════════════════════╣',
|
|
158
|
+
];
|
|
159
|
+
for (const field of secretsInConfig) {
|
|
160
|
+
const envVar = exports.ENV_VAR_MAPPING[field];
|
|
161
|
+
lines.push(`║ ${field.padEnd(25)} → ${envVar.padEnd(30)} ║`);
|
|
162
|
+
}
|
|
163
|
+
lines.push('╠════════════════════════════════════════════════════════════════╣');
|
|
164
|
+
lines.push('║ Run: npx dbdock migrate-config ║');
|
|
165
|
+
lines.push('╚════════════════════════════════════════════════════════════════╝');
|
|
166
|
+
lines.push('');
|
|
167
|
+
return lines.join('\n');
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=secrets.validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.validator.js","sourceRoot":"","sources":["../../src/config/secrets.validator.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Logger as NestLogger } from '@nestjs/common';
|
|
2
|
+
export declare function maskCredentials(message: string): string;
|
|
2
3
|
export declare class DBDockLogger extends NestLogger {
|
|
4
|
+
log(message: string, ...optionalParams: unknown[]): void;
|
|
5
|
+
error(message: string, ...optionalParams: unknown[]): void;
|
|
6
|
+
warn(message: string, ...optionalParams: unknown[]): void;
|
|
7
|
+
debug(message: string, ...optionalParams: unknown[]): void;
|
|
8
|
+
verbose(message: string, ...optionalParams: unknown[]): void;
|
|
3
9
|
logBackupStart(backupId: string, type: string): void;
|
|
4
10
|
logBackupComplete(backupId: string, duration: number, size: number): void;
|
|
5
11
|
logBackupError(backupId: string, error: Error): void;
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DBDockLogger = void 0;
|
|
4
|
+
exports.maskCredentials = maskCredentials;
|
|
4
5
|
const common_1 = require("@nestjs/common");
|
|
6
|
+
const SENSITIVE_PATTERNS = [
|
|
7
|
+
{ pattern: /password['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'password: ********' },
|
|
8
|
+
{ pattern: /secret['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'secret: ********' },
|
|
9
|
+
{ pattern: /accesskey['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'accessKey: ********' },
|
|
10
|
+
{ pattern: /secretkey['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'secretKey: ********' },
|
|
11
|
+
{ pattern: /apikey['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'apiKey: ********' },
|
|
12
|
+
{ pattern: /apisecret['":\s]*['"]?([^'"}\s,]+)/gi, replacement: 'apiSecret: ********' },
|
|
13
|
+
{ pattern: /webhook['":\s]*['"]?(https?:\/\/[^'"}\s,]+)/gi, replacement: 'webhook: ********' },
|
|
14
|
+
{ pattern: /PGPASSWORD=([^\s]+)/gi, replacement: 'PGPASSWORD=********' },
|
|
15
|
+
{ pattern: /Bearer\s+([A-Za-z0-9\-._~+/]+=*)/gi, replacement: 'Bearer ********' },
|
|
16
|
+
{ pattern: /Basic\s+([A-Za-z0-9+/]+=*)/gi, replacement: 'Basic ********' },
|
|
17
|
+
];
|
|
18
|
+
function maskCredentials(message) {
|
|
19
|
+
let masked = message;
|
|
20
|
+
for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
|
|
21
|
+
masked = masked.replace(pattern, replacement);
|
|
22
|
+
}
|
|
23
|
+
return masked;
|
|
24
|
+
}
|
|
5
25
|
class DBDockLogger extends common_1.Logger {
|
|
26
|
+
log(message, ...optionalParams) {
|
|
27
|
+
super.log(maskCredentials(message), ...optionalParams);
|
|
28
|
+
}
|
|
29
|
+
error(message, ...optionalParams) {
|
|
30
|
+
super.error(maskCredentials(message), ...optionalParams);
|
|
31
|
+
}
|
|
32
|
+
warn(message, ...optionalParams) {
|
|
33
|
+
super.warn(maskCredentials(message), ...optionalParams);
|
|
34
|
+
}
|
|
35
|
+
debug(message, ...optionalParams) {
|
|
36
|
+
super.debug(maskCredentials(message), ...optionalParams);
|
|
37
|
+
}
|
|
38
|
+
verbose(message, ...optionalParams) {
|
|
39
|
+
super.verbose(maskCredentials(message), ...optionalParams);
|
|
40
|
+
}
|
|
6
41
|
logBackupStart(backupId, type) {
|
|
7
42
|
this.log(`Backup started: ${backupId} (type: ${type})`);
|
|
8
43
|
}
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbdock",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Enterprise-grade PostgreSQL backup and restore in under 60 seconds. CLI-first tool with encryption, compression, and multi-cloud storage.",
|
|
5
5
|
"author": "Naheem Olaide <naheemolaide@gmail.com>",
|
|
6
6
|
"private": false,
|