Skip to content

Instantly share code, notes, and snippets.

@qoomon
Created October 26, 2020 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qoomon/12e1da16a6fead9a1991d60486a37019 to your computer and use it in GitHub Desktop.
Save qoomon/12e1da16a6fead9a1991d60486a37019 to your computer and use it in GitHub Desktop.
clipperz export to enpass converter
#!/usr/bin/env node
// requirenments
// npm install --save \node-html-parser uuid
const fs = require('fs')
const parseHtml = require('node-html-parser').parse
const uuid = require('uuid').v4
Array.prototype.lastItem = function() {
return this[this.length - 1]
}
const clipperz = {
tagDelimiter: ' ',
archiveTag: 'ARCH',
}
function mapClipperzField2EnpassType(clipperz_field) {
clipperz_fieldLabel = clipperz_field.label.toLowerCase().trim()
clipperz_fieldValue = clipperz_field.value
if ([
/password/,
/passwort/,
/kennwort/,
/keyword/,
/schlüssel(\s|$)/,
/key(\s|$)/,
/passphrase(\s|$)/,
].find(pattern => clipperz_fieldLabel.match(pattern))) {
return 'password'
}
if ([
/^user$/,
/^username$/,
/^nutzername$/,
/^login name$/,
/^login$/,
/^login id$/,
].find(pattern => clipperz_fieldLabel.match(pattern))) {
return 'username'
}
if ([
/email/,
/e-mail/,
].find(pattern => clipperz_fieldLabel.match(pattern)) ||
[
/[a-zA-Z0-9.\-+_]+@[a-zA-Z0-9.\-+]+\.[a-zA-Z]+$/
].find(pattern => clipperz_fieldValue.match(pattern))) {
return 'email'
}
if ([
/url(\s|$)/,
/website(\s|$)/,
/homepage(\s|$)/,
/(^|\s)link(\s|$)/,
].find(pattern => clipperz_fieldLabel.match(pattern))) {
return 'url'
}
if ([
/pin(\s|$)/,
].find(pattern => clipperz_fieldLabel.match(pattern))) {
return 'pin'
}
return 'text'
}
const clipperz_export_file = process.argv[2]
const clipperz_export_html = fs.readFileSync(clipperz_export_file, 'utf8')
const clipperz_export = parseHtml(clipperz_export_html)
const clipperz_entries_json = clipperz_export.querySelector("body div div textarea").text
const clipperz_entries = JSON.parse(clipperz_entries_json)
let enpass_import = {
folders: [],
items: [],
}
clipperz_entries.forEach(clipperz_entry => {
let clipperz_labelSplit = clipperz_entry.label.split(clipperz.tagDelimiter)
let clipperz_label = clipperz_labelSplit[0]
let clipperz_tags = clipperz_labelSplit.slice(1)
let title = clipperz_label
let tags = clipperz_tags.map(t => t == clipperz.archiveTag ? 'Archived' : t)
let fields = Object.values(clipperz_entry.currentVersion.fields).map(clipperz_field => {
let field = {
label: clipperz_field.label,
type: mapClipperzField2EnpassType(clipperz_field),
value: clipperz_field.value,
}
if (clipperz_field.hidden) {
field.sensitive = 1
}
return field
})
let folders = tags.map(tag => {
let folder = enpass_import.folders.find(f => f.title == tag)
if (!folder) {
folder = {
title: tag,
uuid: uuid(),
}
enpass_import.folders.push(folder)
}
return folder.uuid
})
let notes = clipperz_entry.data.notes
if (!notes.trim()) {
notes = ''
}
enpass_import.items.push({
template_type: "empty",
title,
fields,
notes,
folders,
})
});
console.log(JSON.stringify(enpass_import, null, 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment