зеркало из https://github.com/mozilla/gecko-dev.git
258 строки
7.2 KiB
JavaScript
258 строки
7.2 KiB
JavaScript
/* 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";
|
|
|
|
this.EXPORTED_SYMBOLS = ["MobileIdentityCredentialsStore"];
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
|
|
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
|
Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
|
|
Cu.import("resource://gre/modules/Promise.jsm");
|
|
|
|
const CREDENTIALS_DB_NAME = "mobile-id-credentials";
|
|
const CREDENTIALS_DB_VERSION = 1;
|
|
const CREDENTIALS_STORE_NAME = "credentials-store";
|
|
|
|
this.MobileIdentityCredentialsStore = function() {
|
|
};
|
|
|
|
this.MobileIdentityCredentialsStore.prototype = {
|
|
|
|
__proto__: IndexedDBHelper.prototype,
|
|
|
|
init: function() {
|
|
log.debug("MobileIdentityCredentialsStore init");
|
|
this.initDBHelper(CREDENTIALS_DB_NAME,
|
|
CREDENTIALS_DB_VERSION,
|
|
[CREDENTIALS_STORE_NAME]);
|
|
},
|
|
|
|
upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
|
|
log.debug("upgradeSchema");
|
|
/**
|
|
* We will be storing objects like:
|
|
* {
|
|
* msisdn: <string> (key),
|
|
* iccId: <string> (index, optional),
|
|
* deviceIccIds: <array>,
|
|
* origin: <array> (index),
|
|
* msisdnSessionToken: <string>,
|
|
* }
|
|
*/
|
|
let objectStore = aDb.createObjectStore(CREDENTIALS_STORE_NAME, {
|
|
keyPath: "msisdn"
|
|
});
|
|
|
|
objectStore.createIndex("iccId", "iccId", { unique: true });
|
|
objectStore.createIndex("origin", "origin", { unique: true, multiEntry: true });
|
|
},
|
|
|
|
add: function(aIccId, aMsisdn, aOrigin, aSessionToken, aDeviceIccIds) {
|
|
log.debug("put " + aIccId + ", " + aMsisdn + ", " + aOrigin + ", " +
|
|
aSessionToken + ", " + aDeviceIccIds);
|
|
if (!aOrigin || !aSessionToken) {
|
|
return Promise.reject(ERROR_INTERNAL_DB_ERROR);
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
|
|
// We first try get an existing record for the given MSISDN.
|
|
this.newTxn(
|
|
"readwrite",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
let range = IDBKeyRange.only(aMsisdn);
|
|
let cursorReq = aStore.openCursor(range);
|
|
cursorReq.onsuccess = function(aEvent) {
|
|
let cursor = aEvent.target.result;
|
|
let record;
|
|
// If we already have a record of this MSISDN, we add the origin to
|
|
// the list of allowed origins.
|
|
if (cursor && cursor.value) {
|
|
record = cursor.value;
|
|
if (record.origin.indexOf(aOrigin) == -1) {
|
|
record.origin.push(aOrigin);
|
|
}
|
|
cursor.update(record);
|
|
} else {
|
|
// Otherwise, we store a new record.
|
|
record = {
|
|
iccId: aIccId,
|
|
msisdn: aMsisdn,
|
|
origin: [aOrigin],
|
|
sessionToken: aSessionToken,
|
|
deviceIccIds: aDeviceIccIds
|
|
};
|
|
aStore.add(record);
|
|
}
|
|
deferred.resolve();
|
|
};
|
|
cursorReq.onerror = function(aEvent) {
|
|
log.error(aEvent.target.error);
|
|
deferred.reject(ERROR_INTERNAL_DB_ERROR);
|
|
};
|
|
}, null, deferred.reject);
|
|
|
|
return deferred.promise;
|
|
},
|
|
|
|
getByMsisdn: function(aMsisdn) {
|
|
log.debug("getByMsisdn " + aMsisdn);
|
|
if (!aMsisdn) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
this.newTxn(
|
|
"readonly",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
aStore.get(aMsisdn).onsuccess = function(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
};
|
|
},
|
|
function(result) {
|
|
deferred.resolve(result);
|
|
},
|
|
deferred.reject
|
|
);
|
|
return deferred.promise;
|
|
},
|
|
|
|
getByIndex: function(aIndex, aValue) {
|
|
log.debug("getByIndex " + aIndex + ", " + aValue);
|
|
if (!aValue || !aIndex) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
this.newTxn(
|
|
"readonly",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
let index = aStore.index(aIndex);
|
|
index.get(aValue).onsuccess = function(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
};
|
|
},
|
|
function(result) {
|
|
deferred.resolve(result);
|
|
},
|
|
deferred.reject
|
|
);
|
|
return deferred.promise;
|
|
},
|
|
|
|
getByOrigin: function(aOrigin) {
|
|
return this.getByIndex("origin", aOrigin);
|
|
},
|
|
|
|
getByIccId: function(aIccId) {
|
|
return this.getByIndex("iccId", aIccId);
|
|
},
|
|
|
|
delete: function(aMsisdn) {
|
|
log.debug("delete " + aMsisdn);
|
|
if (!aMsisdn) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
this.newTxn(
|
|
"readwrite",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
aStore.delete(aMsisdn);
|
|
},
|
|
deferred.resolve,
|
|
deferred.reject
|
|
);
|
|
return deferred.promise;
|
|
},
|
|
|
|
removeValue: function(aMsisdn, aKey, aValue) {
|
|
log.debug("Removing " + aKey + " with value " + aValue);
|
|
if (!aMsisdn || !aKey) {
|
|
return Promise.reject();
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
this.newTxn(
|
|
"readwrite",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
let range = IDBKeyRange.only(aMsisdn);
|
|
let cursorReq = aStore.openCursor(range);
|
|
cursorReq.onsuccess = function(aEvent) {
|
|
let cursor = aEvent.target.result;
|
|
let record;
|
|
if (!cursor || !cursor.value) {
|
|
return Promise.resolve();
|
|
}
|
|
record = cursor.value;
|
|
if (!record[aKey]) {
|
|
return Promise.reject();
|
|
}
|
|
if (aValue) {
|
|
let index = record[aKey].indexOf(aValue);
|
|
if (index != -1) {
|
|
record[aKey].splice(index, 1);
|
|
}
|
|
} else {
|
|
record[aKey] = undefined;
|
|
}
|
|
log.debug("Removal done ${}", record);
|
|
cursor.update(record);
|
|
deferred.resolve();
|
|
};
|
|
cursorReq.onerror = function(aEvent) {
|
|
log.error(aEvent.target.error);
|
|
deferred.reject(ERROR_INTERNAL_DB_ERROR);
|
|
};
|
|
}, null, deferred.reject);
|
|
|
|
return deferred.promise;
|
|
},
|
|
|
|
removeOrigin: function(aMsisdn, aOrigin) {
|
|
log.debug("removeOrigin " + aMsisdn + " " + aOrigin);
|
|
return this.removeValue(aMsisdn, "origin", aOrigin);
|
|
},
|
|
|
|
setDeviceIccIds: function(aMsisdn, aDeviceIccIds) {
|
|
log.debug("Setting icc ids " + aDeviceIccIds + " for " + aMsisdn);
|
|
if (!aMsisdn) {
|
|
return Promise.reject();
|
|
}
|
|
|
|
let deferred = Promise.defer();
|
|
this.newTxn(
|
|
"readwrite",
|
|
CREDENTIALS_STORE_NAME,
|
|
(aTxn, aStore) => {
|
|
let range = IDBKeyRange.only(aMsisdn);
|
|
let cursorReq = aStore.openCursor(range);
|
|
cursorReq.onsuccess = function(aEvent) {
|
|
let cursor = aEvent.target.result;
|
|
let record;
|
|
if (!cursor || !cursor.value) {
|
|
return Promise.resolve();
|
|
}
|
|
record = cursor.value;
|
|
record.deviceIccIds = aDeviceIccIds;
|
|
cursor.update(record);
|
|
deferred.resolve();
|
|
};
|
|
cursorReq.onerror = function(aEvent) {
|
|
log.error(aEvent.target.error);
|
|
deferred.reject(ERROR_INTERNAL_DB_ERROR);
|
|
};
|
|
}, null, deferred.reject);
|
|
|
|
return deferred.promise;
|
|
}
|
|
};
|