summaryrefslogtreecommitdiffstats
path: root/browser/components/migration/IEProfileMigrator.sys.mjs
blob: d0fd504e1a3ee21339d9870ef78a0a36f901639f (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* 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/. */

import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs";
import { MigratorBase } from "resource:///modules/MigratorBase.sys.mjs";
import { MSMigrationUtils } from "resource:///modules/MSMigrationUtils.sys.mjs";

import { PlacesUtils } from "resource://gre/modules/PlacesUtils.sys.mjs";

// Resources

function History() {}

History.prototype = {
  type: MigrationUtils.resourceTypes.HISTORY,

  get exists() {
    return true;
  },

  migrate: function H_migrate(aCallback) {
    let pageInfos = [];
    let typedURLs = MSMigrationUtils.getTypedURLs(
      "Software\\Microsoft\\Internet Explorer"
    );
    let now = new Date();
    let maxDate = new Date(
      Date.now() - MigrationUtils.HISTORY_MAX_AGE_IN_MILLISECONDS
    );

    for (let entry of Cc[
      "@mozilla.org/profile/migrator/iehistoryenumerator;1"
    ].createInstance(Ci.nsISimpleEnumerator)) {
      let url = entry.get("uri").QueryInterface(Ci.nsIURI);
      // MSIE stores some types of URLs in its history that we don't handle,
      // like HTMLHelp and others.  Since we don't properly map handling for
      // all of them we just avoid importing them.
      if (!["http", "https", "ftp", "file"].includes(url.scheme)) {
        continue;
      }

      let title = entry.get("title");
      // Embed visits have no title and don't need to be imported.
      if (!title.length) {
        continue;
      }

      // The typed urls are already fixed-up, so we can use them for comparison.
      let transition = typedURLs.has(url.spec)
        ? PlacesUtils.history.TRANSITIONS.LINK
        : PlacesUtils.history.TRANSITIONS.TYPED;

      let time = entry.get("time");

      let visitDate = time ? PlacesUtils.toDate(time) : null;
      if (visitDate && visitDate < maxDate) {
        continue;
      }

      pageInfos.push({
        url,
        title,
        visits: [
          {
            transition,
            // use the current date if we have no visits for this entry.
            date: visitDate ?? now,
          },
        ],
      });
    }

    // Check whether there is any history to import.
    if (!pageInfos.length) {
      aCallback(true);
      return;
    }

    MigrationUtils.insertVisitsWrapper(pageInfos).then(
      () => aCallback(true),
      () => aCallback(false)
    );
  },
};

/**
 * Internet Explorer profile migrator
 */
export class IEProfileMigrator extends MigratorBase {
  static get key() {
    return "ie";
  }

  static get displayNameL10nID() {
    return "migration-wizard-migrator-display-name-ie";
  }

  static get brandImage() {
    return "chrome://browser/content/migration/brands/ie.png";
  }

  getResources() {
    let resources = [MSMigrationUtils.getBookmarksMigrator(), new History()];
    let windowsVaultFormPasswordsMigrator =
      MSMigrationUtils.getWindowsVaultFormPasswordsMigrator();
    windowsVaultFormPasswordsMigrator.name = "IEVaultFormPasswords";
    resources.push(windowsVaultFormPasswordsMigrator);
    return resources.filter(r => r.exists);
  }

  async getLastUsedDate() {
    const datePromises = ["Favs", "CookD"].map(dirId => {
      const { path } = Services.dirsvc.get(dirId, Ci.nsIFile);
      return IOUtils.stat(path)
        .then(info => info.lastModified)
        .catch(() => 0);
    });

    const dates = await Promise.all(datePromises);

    try {
      const typedURLs = MSMigrationUtils.getTypedURLs(
        "Software\\Microsoft\\Internet Explorer"
      );
      // typedURLs.values() returns an array of PRTimes, which are in
      // microseconds - convert to milliseconds
      dates.push(Math.max(0, ...typedURLs.values()) / 1000);
    } catch (ex) {}

    return new Date(Math.max(...dates));
  }
}