summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/LoginExport.jsm
blob: ef0cf790fee42bdaf9c7ca253df9d7dab8c44aef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/**
 * Module to support exporting logins to a .csv file.
 */

const EXPORTED_SYMBOLS = ["LoginExport"];

class LoginExport {
  /**
   * Builds an array of strings representing a row in a CSV.
   *
   * @param {nsILoginInfo} login
   *        The object that will be converted into a csv row.
   * @param {string[]} columns
   *        The CSV columns, used to find the properties from the login object.
   * @returns {string[]} Representing a row.
   */
  static _buildCSVRow(login, columns) {
    let row = [];
    for (let columnName of columns) {
      let columnValue = login[columnName];
      if (typeof columnValue == "string") {
        columnValue = columnValue.split('"').join('""');
      }
      if (columnValue !== null && columnValue != undefined) {
        row.push(`"${columnValue}"`);
      } else {
        row.push("");
      }
    }
    return row;
  }

  /**
   * Given a path it saves all the logins as a CSV file.
   *
   * @param {string} path
   *        The file path to save the login to.
   * @param {nsILoginInfo[]} [logins = null]
   *        An optional list of logins.
   */
  static async exportAsCSV(path, logins = null) {
    if (!logins) {
      logins = await Services.logins.getAllLoginsAsync();
    }
    let columns = [
      "origin",
      "username",
      "password",
      "httpRealm",
      "formActionOrigin",
      "guid",
      "timeCreated",
      "timeLastUsed",
      "timePasswordChanged",
    ];
    let csvHeader = columns.map(name => {
      if (name == "origin") {
        return '"url"';
      }
      return `"${name}"`;
    });

    let rows = [];
    rows.push(csvHeader);
    for (let login of logins) {
      rows.push(LoginExport._buildCSVRow(login, columns));
    }
    // https://tools.ietf.org/html/rfc7111 suggests always using CRLF.
    const csvAsString = rows.map(e => e.join(",")).join("\r\n");
    await IOUtils.writeUTF8(path, csvAsString, {
      tmpPath: path + ".tmp",
    });
  }
}