/// <inheritdoc />
 public override object ReadJson(
     JsonReader reader,
     Type objectType,
     object existingValue,
     JsonSerializer serializer)
 {
     return(NssUtils.DecodeAndDecrypt((string)reader.Value));
 }
        /// <summary>
        /// Reads and parses <see cref="Signon"/>s from the <c>signons.sqlite</c> database.
        /// </summary>
        /// <param name="path">The absolute path to the <c>signons.sqlite</c> file.</param>
        /// <returns>The parsed <see cref="Signon"/>s.</returns>
        internal static IEnumerable <Signon> ParseDatabase(string path)
        {
            var connectionBuilder = new SQLiteConnectionStringBuilder
            {
                DataSource    = path,
                Version       = 3,
                FailIfMissing = true,
                ReadOnly      = true
            };

            const string CommandText =
                @"SELECT
                        hostname,
                        httpRealm,
                        formSubmitURL,
                        usernameField,
                        passwordField,
                        encryptedUsername,
                        encryptedPassword,
                        timeCreated,
                        timeLastUsed,
                        timePasswordChanged,
                        timesUsed
                    FROM moz_logins
                    ORDER BY hostname";

            // Doesn't handle exceptions since they were just being rethrown anyway. Default messages are adequately descriptive.
            using (var connection = new SQLiteConnection(connectionBuilder.ConnectionString).OpenAndReturn())
                using (var command = new SQLiteCommand(CommandText, connection))
                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            yield return(new Signon
                            {
                                Hostname = reader.GetString("hostname"),
                                HttpRealm = reader.GetString("httpRealm"),
                                Username = NssUtils.DecodeAndDecrypt(reader.GetString("encryptedUsername")),
                                UserNameField = reader.GetString("usernameField"),
                                Password = NssUtils.DecodeAndDecrypt(reader.GetString("encryptedPassword")),
                                PasswordField = reader.GetString("passwordField"),
                                FormSubmitUrl = reader.GetString("formSubmitURL"),
                                TimeCreated = UnixTimeConverter.Convert(reader.GetNullableUInt64("timeCreated")),
                                TimeLastUsed = UnixTimeConverter.Convert(reader.GetNullableUInt64("timeLastUsed")),
                                TimePasswordChanged = UnixTimeConverter.Convert(reader.GetNullableUInt64("timePasswordChanged")),
                                TimesUsed = reader.GetUInt64("timesUsed")
                            });
                        }
                    }
        }