idb-bridge: enforce store restrictions
This commit is contained in:
parent
706c07fa1d
commit
b41ae3e98d
@ -81,6 +81,11 @@ interface Database {
|
|||||||
|
|
||||||
txLevel: TransactionLevel;
|
txLevel: TransactionLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object stores that the transaction is allowed to access.
|
||||||
|
*/
|
||||||
|
txRestrictObjectStores: string[] | undefined;
|
||||||
|
|
||||||
connectionCookie: string | undefined;
|
connectionCookie: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,6 +320,7 @@ export class MemoryBackend implements Backend {
|
|||||||
connectionCookie: undefined,
|
connectionCookie: undefined,
|
||||||
modifiedObjectStores: {},
|
modifiedObjectStores: {},
|
||||||
txLevel: TransactionLevel.Disconnected,
|
txLevel: TransactionLevel.Disconnected,
|
||||||
|
txRestrictObjectStores: undefined,
|
||||||
};
|
};
|
||||||
this.databases[dbName] = db;
|
this.databases[dbName] = db;
|
||||||
}
|
}
|
||||||
@ -437,6 +443,7 @@ export class MemoryBackend implements Backend {
|
|||||||
modifiedObjectStores: {},
|
modifiedObjectStores: {},
|
||||||
txLevel: TransactionLevel.Disconnected,
|
txLevel: TransactionLevel.Disconnected,
|
||||||
connectionCookie: undefined,
|
connectionCookie: undefined,
|
||||||
|
txRestrictObjectStores: undefined,
|
||||||
};
|
};
|
||||||
this.databases[name] = database;
|
this.databases[name] = database;
|
||||||
}
|
}
|
||||||
@ -446,6 +453,7 @@ export class MemoryBackend implements Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
database.txLevel = TransactionLevel.Connected;
|
database.txLevel = TransactionLevel.Connected;
|
||||||
|
database.txRestrictObjectStores = undefined;
|
||||||
database.connectionCookie = connectionCookie;
|
database.connectionCookie = connectionCookie;
|
||||||
|
|
||||||
const myConn: Connection = {
|
const myConn: Connection = {
|
||||||
@ -493,6 +501,8 @@ export class MemoryBackend implements Backend {
|
|||||||
throw Error("unsupported transaction mode");
|
throw Error("unsupported transaction mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myDb.txRestrictObjectStores = [...objectStores];
|
||||||
|
|
||||||
this.connectionsByTransaction[transactionCookie] = myConn;
|
this.connectionsByTransaction[transactionCookie] = myConn;
|
||||||
|
|
||||||
return { transactionCookie };
|
return { transactionCookie };
|
||||||
@ -520,6 +530,7 @@ export class MemoryBackend implements Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
myDb.txLevel = TransactionLevel.VersionChange;
|
myDb.txLevel = TransactionLevel.VersionChange;
|
||||||
|
myDb.txRestrictObjectStores = undefined;
|
||||||
|
|
||||||
this.connectionsByTransaction[transactionCookie] = myConn;
|
this.connectionsByTransaction[transactionCookie] = myConn;
|
||||||
|
|
||||||
@ -542,6 +553,7 @@ export class MemoryBackend implements Backend {
|
|||||||
throw Error("invalid state");
|
throw Error("invalid state");
|
||||||
}
|
}
|
||||||
myDb.txLevel = TransactionLevel.Disconnected;
|
myDb.txLevel = TransactionLevel.Disconnected;
|
||||||
|
myDb.txRestrictObjectStores = undefined;
|
||||||
}
|
}
|
||||||
delete this.connections[conn.connectionCookie];
|
delete this.connections[conn.connectionCookie];
|
||||||
this.disconnectCond.trigger();
|
this.disconnectCond.trigger();
|
||||||
@ -846,6 +858,16 @@ export class MemoryBackend implements Backend {
|
|||||||
if (db.txLevel < TransactionLevel.Write) {
|
if (db.txLevel < TransactionLevel.Write) {
|
||||||
throw Error("only allowed in write transaction");
|
throw Error("only allowed in write transaction");
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
db.txRestrictObjectStores &&
|
||||||
|
!db.txRestrictObjectStores.includes(objectStoreName)
|
||||||
|
) {
|
||||||
|
throw Error(
|
||||||
|
`Not allowed to access store '${
|
||||||
|
objectStoreName
|
||||||
|
}', transaction is over ${JSON.stringify(db.txRestrictObjectStores)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (typeof range !== "object") {
|
if (typeof range !== "object") {
|
||||||
throw Error("deleteRecord got invalid range (must be object)");
|
throw Error("deleteRecord got invalid range (must be object)");
|
||||||
}
|
}
|
||||||
@ -997,6 +1019,16 @@ export class MemoryBackend implements Backend {
|
|||||||
if (db.txLevel < TransactionLevel.Read) {
|
if (db.txLevel < TransactionLevel.Read) {
|
||||||
throw Error("only allowed while running a transaction");
|
throw Error("only allowed while running a transaction");
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
db.txRestrictObjectStores &&
|
||||||
|
!db.txRestrictObjectStores.includes(req.objectStoreName)
|
||||||
|
) {
|
||||||
|
throw Error(
|
||||||
|
`Not allowed to access store '${
|
||||||
|
req.objectStoreName
|
||||||
|
}', transaction is over ${JSON.stringify(db.txRestrictObjectStores)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
const objectStoreMapEntry = myConn.objectStoreMap[req.objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[req.objectStoreName];
|
||||||
if (!objectStoreMapEntry) {
|
if (!objectStoreMapEntry) {
|
||||||
throw Error("object store not found");
|
throw Error("object store not found");
|
||||||
@ -1314,6 +1346,16 @@ export class MemoryBackend implements Backend {
|
|||||||
if (db.txLevel < TransactionLevel.Write) {
|
if (db.txLevel < TransactionLevel.Write) {
|
||||||
throw Error("only allowed while running a transaction");
|
throw Error("only allowed while running a transaction");
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
db.txRestrictObjectStores &&
|
||||||
|
!db.txRestrictObjectStores.includes(storeReq.objectStoreName)
|
||||||
|
) {
|
||||||
|
throw Error(
|
||||||
|
`Not allowed to access store '${
|
||||||
|
storeReq.objectStoreName
|
||||||
|
}', transaction is over ${JSON.stringify(db.txRestrictObjectStores)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
const schema = myConn.modifiedSchema;
|
const schema = myConn.modifiedSchema;
|
||||||
const objectStoreMapEntry = myConn.objectStoreMap[storeReq.objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[storeReq.objectStoreName];
|
||||||
|
|
||||||
@ -1363,7 +1405,7 @@ export class MemoryBackend implements Backend {
|
|||||||
console.error("key was:", storeReq.key);
|
console.error("key was:", storeReq.key);
|
||||||
}
|
}
|
||||||
throw new DataError(m);
|
throw new DataError(m);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1482,6 +1524,7 @@ export class MemoryBackend implements Backend {
|
|||||||
}
|
}
|
||||||
db.modifiedObjectStores = {};
|
db.modifiedObjectStores = {};
|
||||||
db.txLevel = TransactionLevel.Connected;
|
db.txLevel = TransactionLevel.Connected;
|
||||||
|
db.txRestrictObjectStores = undefined;
|
||||||
myConn.modifiedSchema = structuredClone(db.committedSchema);
|
myConn.modifiedSchema = structuredClone(db.committedSchema);
|
||||||
myConn.objectStoreMap = this.makeObjectStoreMap(db);
|
myConn.objectStoreMap = this.makeObjectStoreMap(db);
|
||||||
for (const objectStoreName in db.committedObjectStores) {
|
for (const objectStoreName in db.committedObjectStores) {
|
||||||
@ -1524,6 +1567,7 @@ export class MemoryBackend implements Backend {
|
|||||||
|
|
||||||
db.committedSchema = structuredClone(myConn.modifiedSchema);
|
db.committedSchema = structuredClone(myConn.modifiedSchema);
|
||||||
db.txLevel = TransactionLevel.Connected;
|
db.txLevel = TransactionLevel.Connected;
|
||||||
|
db.txRestrictObjectStores = undefined;
|
||||||
|
|
||||||
db.committedObjectStores = {};
|
db.committedObjectStores = {};
|
||||||
db.committedObjectStores = {};
|
db.committedObjectStores = {};
|
||||||
|
Loading…
Reference in New Issue
Block a user