Forked from nikspyratos/protonpass_to_keepassxc.js
Last active
December 7, 2024 02:09
-
-
Save TheMeaner0/cb54486fc5748734a829a3181fa6e0bf to your computer and use it in GitHub Desktop.
Proton Pass json export file -> KeePassXC import CSV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Fork of the original `proton_to_keepassxc.js` script by nikspyratos | |
* Original script: https://gist.github.com/nikspyratos/bd0b5ef05a4d82d2d0425cb4be9844db | |
* | |
* This fork fixed a bug with how Proton Pass stores usernames and emails in its JSON export. | |
* Proton Pass uses separate JSON tags for emails (`itemEmail`) and usernames (`itemUsername`). | |
* KeePassXC imports only the `itemUsername` field, which makes it so there might be missing data. | |
* the username is stored under the `itemEmail` tag instead. | |
* | |
* This fork fixes the bug in the original script by checking both tags and using one if the other is not available. | |
* | |
*/ | |
#!/usr/bin/env node | |
const fs = require('fs'); | |
function convertProtonPassToJson(protonPassJson) { | |
// Parse the JSON input | |
const data = JSON.parse(protonPassJson); | |
// Define an array to hold CSV lines | |
let csvLines = []; | |
// CSV header line | |
csvLines.push("Group,Title,Username,Password,URL,Notes,TOTP,Icon,Last Modified,Created"); | |
// Process each vault | |
Object.values(data.vaults).forEach(vault => { | |
// Skip the vault if its name is "Recycle Bin" | |
if (vault.name === "Recycle Bin") { | |
return; | |
} | |
// Process each item in the vault | |
vault.items?.forEach(item => { | |
const itemData = item.data.content; | |
const modifiedTime = item.modifyTime ? new Date(item.modifyTime * 1000).toISOString() : ''; | |
const createdTime = item.createTime ? new Date(item.createTime * 1000).toISOString() : ''; | |
// Determine the username (use 'itemUsername' or fall back to 'itemEmail') | |
const username = itemData?.itemUsername || itemData?.itemEmail || ''; | |
// Escaping newlines in notes and special characters | |
const notesEscaped = item.data.metadata?.note?.replace(/\n/g, '\\n').replace(/"/g, '\\"') || ''; | |
const passwordEscaped = itemData?.password?.replace(/\\/g, '\\\\').replace(/"/g, '\\"') || ''; | |
const line = [ | |
`"${vault.name}"`, | |
`"${item.data.metadata?.name || ''}"`, | |
`"${username}"`, | |
`"${passwordEscaped}"`, | |
`"${itemData?.urls?.join(', ') || ''}"`, | |
`"${notesEscaped}"`, | |
`"${itemData?.totpUri || ''}"`, | |
`""`, // Icon field is left blank as it is not in the JSON | |
`"${modifiedTime}"`, | |
`"${createdTime}"` | |
].join(','); | |
csvLines.push(line); | |
}); | |
}); | |
// Join all lines to create CSV text | |
return csvLines.join('\n'); | |
} | |
// Get the file path from command line arguments | |
const inputFilePath = process.argv[2]; | |
const outputFilePath = process.argv[3]; | |
if (!inputFilePath || !outputFilePath) { | |
console.error("Please provide an input file path and an output file path."); | |
process.exit(1); | |
} | |
const protonPassJson = fs.readFileSync(inputFilePath, 'utf8'); | |
const csvData = convertProtonPassToJson(protonPassJson); | |
fs.writeFileSync(outputFilePath, csvData); | |
console.log(`CSV data written to ${outputFilePath}`); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
./protonpass_to_keepassxc_csv.js {JSON_export} {csv_output}
OR
node protonpass_to_keepassxc_csv.js {JSON_export} {csv_output}
This will output a CSV of your ProtonPass export that you can use for KeePassXC imports and potentially others (unsure, have not tested other password managers).
You will need nodejs installed on your system.
Fork of the original
proton_to_keepassxc.js
script by nikspyratosOriginal script: https://gist.github.com/nikspyratos/bd0b5ef05a4d82d2d0425cb4be9844db