pux-to-html
Advanced tools
Comparing version 1.0.2 to 1.1.0
{ | ||
"name": "pux-to-html", | ||
"version": "1.0.2", | ||
"license": "MIT", | ||
"author": "Roman Ožana <roman@ozana.cz> (https://ozana.cz)", | ||
"description": "Converts 1PUX (export from 1Password) file to HTML files", | ||
"keywords": [ | ||
"1password", | ||
"pux", | ||
"html", | ||
"export", | ||
"security", | ||
"password", | ||
"convert" | ||
], | ||
"repository": "git@github.com:OzzyCzech/pux-to-html.git", | ||
"main": "index.js", | ||
"type": "module", | ||
"dependencies": { | ||
"@sindresorhus/slugify": "^2.2.1", | ||
"adm-zip": "^0.5.12", | ||
"commander": "^12.0.0", | ||
"meow": "^13.2.0" | ||
}, | ||
"devDependencies": { | ||
"xo": "^0.38.0" | ||
}, | ||
"bin": { | ||
"pux2html": "./index.js" | ||
} | ||
"name": "pux-to-html", | ||
"version": "1.1.0", | ||
"license": "MIT", | ||
"author": "Roman Ožana <roman@ozana.cz> (https://ozana.cz)", | ||
"description": "Converts 1PUX (export from 1Password) file to HTML files", | ||
"keywords": [ | ||
"1password", | ||
"pux", | ||
"html", | ||
"export", | ||
"security", | ||
"password", | ||
"convert" | ||
], | ||
"repository": "git@github.com:OzzyCzech/pux-to-html.git", | ||
"main": "index.js", | ||
"type": "module", | ||
"dependencies": { | ||
"@sindresorhus/slugify": "^2.2.1", | ||
"adm-zip": "^0.5.16", | ||
"commander": "^12.1.0", | ||
"meow": "^13.2.0" | ||
}, | ||
"devDependencies": { | ||
"@biomejs/biome": "1.9.4", | ||
"np": "^10.0.7" | ||
}, | ||
"scripts": { | ||
"release": "np", | ||
"format": "biome format --write", | ||
"lint": "biome lint", | ||
"test": "biome ci" | ||
}, | ||
"bin": { | ||
"pux2html": "./index.js" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
export function getHtml({content, title}) { | ||
export function getHtml({ content, title }) { | ||
return `<!doctype html> | ||
@@ -3,0 +3,0 @@ <html lang="en"> |
@@ -13,12 +13,16 @@ function getCopyButton(value) { | ||
function getSection({title, fields}) { | ||
return fields && fields.length > 0 ? ` | ||
${title ? `<h6 class="uppercase font-semibold">${title}</h6>` : ''} | ||
function getSection({ title, fields }) { | ||
return fields && fields.length > 0 | ||
? ` | ||
${title ? `<h6 class="uppercase font-semibold">${title}</h6>` : ""} | ||
<ul class="divide-y border rounded-xl"> | ||
${fields.map(getField).join('')} | ||
</ul>` : ''; | ||
${fields.map(getField).join("")} | ||
</ul>` | ||
: ""; | ||
} | ||
function getNotes({notesPlain}) { | ||
return notesPlain ? `<h6 class="font-semibold">Note</h6><pre class="text-gray-100 bg-gray-900 rounded p-4 m-2">${notesPlain}</pre>` : ''; | ||
function getNotes({ notesPlain }) { | ||
return notesPlain | ||
? `<h6 class="font-semibold">Note</h6><pre class="text-gray-100 bg-gray-900 rounded p-4 m-2">${notesPlain}</pre>` | ||
: ""; | ||
} | ||
@@ -42,4 +46,4 @@ | ||
const link = new URL(url); | ||
const secret = link.searchParams.get('secret'); | ||
const issuer = link.searchParams.get('issuer'); | ||
const secret = link.searchParams.get("secret"); | ||
const issuer = link.searchParams.get("issuer"); | ||
@@ -56,15 +60,16 @@ return `<ul> | ||
function getField({value, name, title, url, label, designation}) { | ||
function getField({ value, name, title, url, label, designation }) { | ||
if (value instanceof Object) { | ||
if (value.hasOwnProperty('url') && value.url) { | ||
const { url, string, totp, concealed, file } = value; | ||
if (url) { | ||
value = getUrl(value.url); | ||
} else if (value.hasOwnProperty('string') && value.string) { | ||
} else if (string) { | ||
value = `<code>${value.string}</code>`; | ||
} else if (value.hasOwnProperty('totp') && value.totp) { | ||
label = 'one-time password'; | ||
} else if (totp) { | ||
label = "one-time password"; | ||
value = getOTP(value.totp); | ||
} else if (value.hasOwnProperty('concealed') && value.concealed) { | ||
} else if (concealed) { | ||
value = getSecret(value.concealed); | ||
} else if (value.hasOwnProperty('file') && value.file) { | ||
label = 'file'; | ||
} else if (file) { | ||
label = "file"; | ||
value = `<code>${value.file.fileName}</code>`; | ||
@@ -77,3 +82,3 @@ } else { | ||
// Password or username fields | ||
if (designation === 'password' || designation === 'username') { | ||
if (designation === "password" || designation === "username") { | ||
value = getSecret(value); | ||
@@ -84,21 +89,33 @@ } | ||
if (url) { | ||
label = 'website'; | ||
label = "website"; | ||
value = getUrl(url); | ||
} | ||
return value ? `<li class="p-3 flex flex-col flex-wrap gap-1"> | ||
return value | ||
? `<li class="p-3 flex flex-col flex-wrap gap-1"> | ||
<div><span class="text-gray-500">${designation || name || title || label}:</span></div> | ||
<div class="flex items-center gap-3">${value}</div> | ||
</li>` : ''; | ||
</li>` | ||
: ""; | ||
} | ||
export function getItemHtml({state, details, overview, createdAt, updatedAt}) { | ||
export function getItemHtml({ | ||
state, | ||
details, | ||
overview, | ||
createdAt, | ||
updatedAt, | ||
}) { | ||
const loginSection = { | ||
fields: [ | ||
...details.loginFields.filter(item => item.designation === 'password' || item.designation === 'username'), | ||
...overview.urls || [] | ||
] | ||
...details.loginFields.filter( | ||
(item) => | ||
item.designation === "password" || item.designation === "username", | ||
), | ||
...(overview.urls || []), | ||
], | ||
}; | ||
return state === 'active' ? ` | ||
return state === "active" | ||
? ` | ||
<article class="border rounded-lg p-6 print:p-4 my-4 break-inside-avoid flex flex-col gap-3"> | ||
@@ -111,3 +128,3 @@ <h2 class="text-3xl print:text-lg font-semibold">${overview.title}</h2> | ||
<!-- other sections --> | ||
${details.sections.map(getSection).join('')} | ||
${details.sections.map(getSection).join("")} | ||
@@ -117,3 +134,4 @@ <!-- notes --> | ||
</article> | ||
` : ''; | ||
` | ||
: ""; | ||
} |
@@ -1,16 +0,14 @@ | ||
import {getHtml} from './get-html.js'; | ||
import {getItemHtml} from './get-item-html.js'; | ||
import { getHtml } from "./get-html.js"; | ||
import { getItemHtml } from "./get-item-html.js"; | ||
export function getVaultHtml({attrs, items}) { | ||
export function getVaultHtml({ attrs, items }) { | ||
items.sort((a, b) => b.updatedAt - a.updatedAt); | ||
return getHtml( | ||
{ | ||
title: `Vault export ${attrs.name}`, | ||
content: ` | ||
return getHtml({ | ||
title: `Vault export ${attrs.name}`, | ||
content: ` | ||
<h1 class="text-2xl">Export of <em>${attrs.name}</em> vault</h1> | ||
${items.map(getItemHtml).join('\n')} | ||
` | ||
} | ||
); | ||
${items.map(getItemHtml).join("\n")} | ||
`, | ||
}); | ||
} |
@@ -1,6 +0,6 @@ | ||
import slugify from '@sindresorhus/slugify'; | ||
import {getVaultHtml} from './get-vault-html.js'; | ||
import {writeFile} from './write-file.js'; | ||
import {join} from 'node:path'; | ||
import AdmZip from 'adm-zip'; | ||
import { join } from "node:path"; | ||
import slugify from "@sindresorhus/slugify"; | ||
import AdmZip from "adm-zip"; | ||
import { getVaultHtml } from "./get-vault-html.js"; | ||
import { writeFile } from "./write-file.js"; | ||
@@ -10,6 +10,6 @@ // Import templates | ||
export async function puxToHtml(input, output) { | ||
const pux = new AdmZip(input); | ||
const pux = new AdmZip(input, {}); | ||
const attributes = JSON.parse(pux.readAsText('export.attributes')); | ||
const data = JSON.parse(pux.readAsText('export.data')); | ||
const attributes = JSON.parse(pux.readAsText("export.attributes", "utf8")); | ||
const data = JSON.parse(pux.readAsText("export.data", "utf8")); | ||
@@ -22,3 +22,3 @@ for (const account of data.accounts) { | ||
for (const vault of account.vaults) { | ||
const fileName = slugify(vault.attrs.name) + '.html'; | ||
const fileName = `${slugify(vault.attrs.name)}.html`; | ||
const html = getVaultHtml(vault); | ||
@@ -25,0 +25,0 @@ |
@@ -1,4 +0,4 @@ | ||
import {mkdir, writeFile as writeFileAsync} from 'node:fs/promises'; | ||
import {existsSync} from 'node:fs'; | ||
import {dirname} from 'node:path'; | ||
import { existsSync } from "node:fs"; | ||
import { mkdir, writeFile as writeFileAsync } from "node:fs/promises"; | ||
import { dirname } from "node:path"; | ||
@@ -14,3 +14,3 @@ /** | ||
if (!existsSync(dirname(file))) { | ||
await mkdir(dirname(file), {recursive: true}); | ||
await mkdir(dirname(file), { recursive: true }); | ||
} | ||
@@ -17,0 +17,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10528
2
211
1
Updatedadm-zip@^0.5.16
Updatedcommander@^12.1.0