1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 this.EXPORTED_SYMBOLS = ["MobileIdentityCredentialsStore"];
9 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
11 Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
12 Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
13 Cu.import("resource://gre/modules/Promise.jsm");
15 const CREDENTIALS_DB_NAME = "mobile-id-credentials";
16 const CREDENTIALS_DB_VERSION = 1;
17 const CREDENTIALS_STORE_NAME = "credentials-store";
19 this.MobileIdentityCredentialsStore = function() {
22 this.MobileIdentityCredentialsStore.prototype = {
24 __proto__: IndexedDBHelper.prototype,
27 log.debug("MobileIdentityCredentialsStore init");
28 this.initDBHelper(CREDENTIALS_DB_NAME,
29 CREDENTIALS_DB_VERSION,
30 [CREDENTIALS_STORE_NAME]);
33 upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
34 log.debug("upgradeSchema");
36 * We will be storing objects like:
38 * msisdn: <string> (key),
39 * iccId: <string> (index, optional),
40 * deviceIccIds: <array>,
41 * origin: <array> (index),
42 * msisdnSessionToken: <string>,
45 let objectStore = aDb.createObjectStore(CREDENTIALS_STORE_NAME, {
49 objectStore.createIndex("iccId", "iccId", { unique: true });
50 objectStore.createIndex("origin", "origin", { unique: true, multiEntry: true });
53 add: function(aIccId, aMsisdn, aOrigin, aSessionToken, aDeviceIccIds) {
54 log.debug("put " + aIccId + ", " + aMsisdn + ", " + aOrigin + ", " +
55 aSessionToken + ", " + aDeviceIccIds);
56 if (!aOrigin || !aSessionToken) {
57 return Promise.reject(ERROR_INTERNAL_DB_ERROR);
60 let deferred = Promise.defer();
62 // We first try get an existing record for the given MSISDN.
65 CREDENTIALS_STORE_NAME,
67 let range = IDBKeyRange.only(aMsisdn);
68 let cursorReq = aStore.openCursor(range);
69 cursorReq.onsuccess = function(aEvent) {
70 let cursor = aEvent.target.result;
72 // If we already have a record of this MSISDN, we add the origin to
73 // the list of allowed origins.
74 if (cursor && cursor.value) {
75 record = cursor.value;
76 if (record.origin.indexOf(aOrigin) == -1) {
77 record.origin.push(aOrigin);
79 cursor.update(record);
81 // Otherwise, we store a new record.
86 sessionToken: aSessionToken,
87 deviceIccIds: aDeviceIccIds
93 cursorReq.onerror = function(aEvent) {
94 log.error(aEvent.target.error);
95 deferred.reject(ERROR_INTERNAL_DB_ERROR);
97 }, null, deferred.reject);
99 return deferred.promise;
102 getByMsisdn: function(aMsisdn) {
103 log.debug("getByMsisdn " + aMsisdn);
105 return Promise.resolve(null);
108 let deferred = Promise.defer();
111 CREDENTIALS_STORE_NAME,
113 aStore.get(aMsisdn).onsuccess = function(aEvent) {
114 aTxn.result = aEvent.target.result;
118 deferred.resolve(result);
122 return deferred.promise;
125 getByIndex: function(aIndex, aValue) {
126 log.debug("getByIndex " + aIndex + ", " + aValue);
127 if (!aValue || !aIndex) {
128 return Promise.resolve(null);
131 let deferred = Promise.defer();
134 CREDENTIALS_STORE_NAME,
136 let index = aStore.index(aIndex);
137 index.get(aValue).onsuccess = function(aEvent) {
138 aTxn.result = aEvent.target.result;
142 deferred.resolve(result);
146 return deferred.promise;
149 getByOrigin: function(aOrigin) {
150 return this.getByIndex("origin", aOrigin);
153 getByIccId: function(aIccId) {
154 return this.getByIndex("iccId", aIccId);
157 delete: function(aMsisdn) {
158 log.debug("delete " + aMsisdn);
160 return Promise.resolve();
163 let deferred = Promise.defer();
166 CREDENTIALS_STORE_NAME,
168 aStore.delete(aMsisdn);
173 return deferred.promise;
176 removeValue: function(aMsisdn, aKey, aValue) {
177 log.debug("Removing " + aKey + " with value " + aValue);
178 if (!aMsisdn || !aKey) {
179 return Promise.reject();
182 let deferred = Promise.defer();
185 CREDENTIALS_STORE_NAME,
187 let range = IDBKeyRange.only(aMsisdn);
188 let cursorReq = aStore.openCursor(range);
189 cursorReq.onsuccess = function(aEvent) {
190 let cursor = aEvent.target.result;
192 if (!cursor || !cursor.value) {
193 return Promise.resolve();
195 record = cursor.value;
197 return Promise.reject();
200 let index = record[aKey].indexOf(aValue);
202 record[aKey].splice(index, 1);
205 record[aKey] = undefined;
207 log.debug("Removal done ${}", record);
208 cursor.update(record);
211 cursorReq.onerror = function(aEvent) {
212 log.error(aEvent.target.error);
213 deferred.reject(ERROR_INTERNAL_DB_ERROR);
215 }, null, deferred.reject);
217 return deferred.promise;
220 removeOrigin: function(aMsisdn, aOrigin) {
221 log.debug("removeOrigin " + aMsisdn + " " + aOrigin);
222 return this.removeValue(aMsisdn, "origin", aOrigin);
225 setDeviceIccIds: function(aMsisdn, aDeviceIccIds) {
226 log.debug("Setting icc ids " + aDeviceIccIds + " for " + aMsisdn);
228 return Promise.reject();
231 let deferred = Promise.defer();
234 CREDENTIALS_STORE_NAME,
236 let range = IDBKeyRange.only(aMsisdn);
237 let cursorReq = aStore.openCursor(range);
238 cursorReq.onsuccess = function(aEvent) {
239 let cursor = aEvent.target.result;
241 if (!cursor || !cursor.value) {
242 return Promise.resolve();
244 record = cursor.value;
245 record.deviceIccIds = aDeviceIccIds;
246 cursor.update(record);
249 cursorReq.onerror = function(aEvent) {
250 log.error(aEvent.target.error);
251 deferred.reject(ERROR_INTERNAL_DB_ERROR);
253 }, null, deferred.reject);
255 return deferred.promise;