UNPKG

realm-object-server

Version:

Realm Object Server

962 lines 50 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const auth = require("../auth"); const TestServer_1 = require("../TestServer"); const Token_1 = require("../shared/Token"); const chai_1 = require("chai"); const chai = require("chai"); const superagent = require("superagent"); const realmUtil_1 = require("../shared/realmUtil"); const uuid = require("uuid"); const path = require("path"); const URI = require("urijs"); const faker = require("faker"); const tmp = require("tmp"); chai.use(require("chai-as-promised")); class RemoteServer { constructor(address) { this.address = address; this.tmpDir = tmp.dirSync().name; realmUtil_1.Realm.Sync.setLogLevel("off"); } get url() { return `http://${this.address}`; } get secureUrl() { return `https://${this.address}`; } get dataPath() { return this.tmpDir; } shutdown() { return __awaiter(this, void 0, void 0, function* () { }); } } class Product { } Product.ProductSchema = { name: "Product", primaryKey: "productId", properties: { productId: { type: "int", optional: false }, name: { type: "string", optional: false }, price: { type: "float", optional: false } } }; describe("Realm-JS integration", function () { const openRealm = (config) => { if (config.sync.fullSynchronization === undefined) { config.sync.fullSynchronization = true; } return new Promise((resolve, reject) => { config.sync.error = (session, err) => reject(err); realmUtil_1.Realm.open(config) .then(resolve) .catch(reject); }); }; const applyPermissions = (user, condition, realmPath, accessLevel) => __awaiter(this, void 0, void 0, function* () { try { yield superagent.post(`${server.url}/permissions/apply`).set({ Authorization: user.token, }) .send({ condition, realmPath, accessLevel, }); } catch (err) { const error = new Error(err.response.body.title); error.statusCode = err.response.body.code; throw error; } }); const getGrantedPermissions = (user, recipient = "any") => __awaiter(this, void 0, void 0, function* () { const response = yield superagent.get(`${server.url}/permissions`).set({ Authorization: user.token, }) .query({ recipient }) .send(); return response.body.permissions; }); const offerPermissions = (user, realmPath, accessLevel, expiresAt) => __awaiter(this, void 0, void 0, function* () { try { const response = yield superagent.post(`${server.url}/permissions/offers`).set({ Authorization: user.token, }) .send({ realmPath, accessLevel, expiresAt, }); return response.body.token; } catch (err) { const error = new Error(err.response.body.title); error.statusCode = err.response.body.code; throw error; } }); const acceptPermissionOffer = (user, token) => __awaiter(this, void 0, void 0, function* () { try { const response = yield superagent.post(`${server.url}/permissions/offers/${token}/accept`).set({ Authorization: user.token, }) .send(); return response.body.path; } catch (err) { const error = new Error(err.response.body.title); error.statusCode = err.response.body.code; throw error; } }); const invalidatePermissionOffer = (user, offerToken) => __awaiter(this, void 0, void 0, function* () { try { yield superagent.delete(`${server.url}/permissions/offers/${offerToken}`).set({ Authorization: user.token, }) .send(); } catch (err) { const error = new Error(err.response.body.title); error.statusCode = err.response.body.code; throw error; } }); let server; before(() => __awaiter(this, void 0, void 0, function* () { if (process.env.REMOTE_ROS) { server = new RemoteServer(process.env.REMOTE_ROS); } else { server = new TestServer_1.TestServer(); yield server.start({ authProviders: [ new auth.PasswordAuthProvider({ autoCreateAdminUser: true, iterations: 1 }), new auth.AnonymousAuthProvider(), new auth.NicknameAuthProvider(), ], https: true, httpsKeyPath: path.join(__dirname, "..", "..", "fixtures", "https.key"), httpsCertChainPath: path.join(__dirname, "..", "..", "fixtures", "https.crt"), logLevel: "off", }); } })); after(function () { return __awaiter(this, void 0, void 0, function* () { this.timeout(20000); if (server) { yield server.shutdown(); } }); }); describe("permissions", () => { let userA; let realmA; let userB; let userBProviderId; let realmAProduct; let adminUser; let permissionRealms = new Array(); beforeEach(() => __awaiter(this, void 0, void 0, function* () { userA = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); userBProviderId = faker.internet.userName(); userB = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword(userBProviderId, "a")); adminUser = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); realmA = yield openRealm({ sync: { user: userA, url: `realm://${server.address}/~/products` }, schema: [Product.ProductSchema] }); realmA.write(() => { realmAProduct = realmA.create("Product", { productId: 0, name: faker.commerce.productName(), price: faker.random.number({ min: 12, max: 7000 }) }); }); })); afterEach(() => { if (realmA) { realmA.close(); } for (const realm of permissionRealms) { realm.close(); } permissionRealms = []; }); function assertExistenceInUserPermissions(user, expected, shouldExist = true) { return __awaiter(this, void 0, void 0, function* () { const perms = yield getGrantedPermissions(user); let matches = perms.filter(p => p.path === expected.path && p.accessLevel === expected.accessLevel); if (expected.userId) { matches = matches.filter(p => p.userId === expected.userId); } if (shouldExist) { chai_1.assert.isAtLeast(matches.length, 1, "Expected at least one match in the granted permissions."); } else { chai_1.assert.equal(matches.length, 0, "Expected no matches in the granted permissions"); } }); } function assertUserPermissions(user, ...expected) { return __awaiter(this, void 0, void 0, function* () { const result = yield getGrantedPermissions(user); for (const e of expected) { const perm = result.slice().filter((p) => { return p.userId === e.userId; }).find((p) => { return p.path === e.path; }); chai_1.assert.isDefined(perm); chai_1.assert.equal(perm.accessLevel, e.accessLevel, `Expected user to have accessLevel=${e.accessLevel}`); } }); } describe("default permissions", () => { describe("with 10 new realms", () => { beforeEach(() => __awaiter(this, void 0, void 0, function* () { for (let i = 0; i < 10; i++) { const realm = yield openRealm({ sync: { user: userA, url: `realm://${server.address}/~/products${i}` }, schema: [Product.ProductSchema] }); realm.close(); } })); it("should receive all 10 permissions", () => __awaiter(this, void 0, void 0, function* () { const result = yield getGrantedPermissions(userA, "currentUser"); for (let i = 0; i < 10; i++) { const permission = result.slice().find((p) => { return p.path === `/${userA.identity}/products${i}`; }); chai_1.assert.isDefined(permission, `Could not find default permission for /~/products${i}`); chai_1.assert.equal(permission.userId, userA.identity); chai_1.assert.equal(permission.accessLevel, "admin"); } })); }); }); describe("changes", function () { this.timeout(300000); describe("wildcard", () => { describe("userA granting read to all users on /~/products", () => { it("userB should be able to read", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: "*" }, "/~/products", "read"); const realm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products`, user: userB, }, schema: [Product.ProductSchema] })); realm.close(); })); }); describe("userA granting read to userB on all realms", () => { it("userB should be able to read /~/products2", () => __awaiter(this, void 0, void 0, function* () { const userARealm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products2`, user: userA, }, schema: [Product.ProductSchema] })); userARealm.close(); yield applyPermissions(userA, { userId: userB.identity }, "*", "read"); const userBRealm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products2`, user: userB, }, schema: [Product.ProductSchema] })); userBRealm.close(); })); }); describe("userA granting read to all users on all realms", () => { it("userB should be able to read /~/products", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: "*" }, "*", "read"); const userBRealm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products`, user: userB, }, schema: [Product.ProductSchema] })); userBRealm.close(); })); }); }); describe("with an invalid user in the path", () => { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const token = Token_1.generateAdminToken({ privateKey: server.privateKey, }); const adminCredentials = realmUtil_1.Realm.Sync.Credentials.adminToken(token); const tokenUser = realmUtil_1.Realm.Sync.User.login(server.url, adminCredentials); yield chai_1.assert.isRejected(applyPermissions(tokenUser, { userId: "*" }, "/__auth/products", "read"), "Your request parameters did not validate."); })); }); describe("to an email address", () => { let userBEmailAddress; beforeEach(() => __awaiter(this, void 0, void 0, function* () { userBEmailAddress = faker.internet.email(); })); describe("invalid email address", () => { it("should throw", () => __awaiter(this, void 0, void 0, function* () { const error = yield chai_1.assert.isRejected(applyPermissions(userA, { metadataKey: "email", metadataValue: userBEmailAddress }, "/~/products", "read"), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); }); describe("userA granting read to userB with just email and no metadata on user", () => { let userB; let userBEmailAddress; beforeEach(() => __awaiter(this, void 0, void 0, function* () { userBEmailAddress = faker.internet.email(); userB = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword(userBEmailAddress, "a")); })); it("should be successful", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { metadataKey: "email", metadataValue: userBEmailAddress }, "/~/products", "read"); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); })); }); describe("userA granting read to userB's email address (metadata)", () => { let adminUser; beforeEach(() => __awaiter(this, void 0, void 0, function* () { adminUser = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); yield superagent.put(`${server.url}/auth/users`).set({ Authorization: adminUser.token, }) .send({ provider_id: userBProviderId, provider: "password", metadata: { email: userBEmailAddress }, user_id: userB.identity }); })); it("should be successful", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { metadataKey: "email", metadataValue: userBEmailAddress }, "/~/products", "read"); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); })); }); }); describe("userA granting read to userB to own __permission realm", () => { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const error = yield chai_1.assert.isRejected(applyPermissions(userA, { userId: userB.identity }, "/~/__permission", "read"), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); }); describe("userA granting read to userB to own __management realm", () => { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const error = yield chai_1.assert.isRejected(applyPermissions(userA, { userId: userB.identity }, "/~/__management", "read"), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); }); describe("userA granting read to userB", () => { it("should be successful", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "read"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); })); }); describe("userA granting write to userB", () => { it("should be successful", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "write"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "write", path: `/${userA.identity}/products` }); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "write", path: `/${userA.identity}/products` }); })); }); describe("userA granting admin to userB", () => { it("should be successful", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "admin"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }); })); }); describe("userA decreasing userB's admin privileges", () => { beforeEach(() => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "admin"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }); })); it("to read-only permissions", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "read"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); })); it("to no permissions at all", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "none"); yield assertExistenceInUserPermissions(userA, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products`, }, false); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }, false); })); }); describe("userA granting write to userB with userC's Realm", () => { it("should fail", () => __awaiter(this, void 0, void 0, function* () { const userC = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const userCRealm = yield openRealm({ sync: { url: `realm://${server.address}/~/products`, user: userC, }, schema: [Product.ProductSchema] }); userCRealm.close(); const err = yield chai_1.assert.isRejected(applyPermissions(userA, { userId: userB.identity }, `/${userC.identity}/products`, "write"), "The path is invalid or current user has no access."); chai_1.assert.equal(err.statusCode, 614); })); }); describe("userA granting read to all", () => { it("should be successful for userB to open", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: "*" }, "/~/products", "read"); const realm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products`, user: userB, }, schema: [Product.ProductSchema] })); realm.close(); })); }); describe("userA granting admin to all", () => { it("should allow userB to change permission to write", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: "*" }, "/~/products", "admin"); yield applyPermissions(userB, { userId: "*" }, `/${userA.identity}/products`, "write"); })); }); describe("adminUser granting write to all for userA's realm", () => { it("should generate a wildcard permission", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(adminUser, { userId: "*" }, `/${userA.identity}/products`, "write"); yield assertExistenceInUserPermissions(userB, { accessLevel: "write", path: `/${userA.identity}/products` }); })); }); describe("userA granting read to all", () => { it("should allow userB to see wildcard permission", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: "*" }, "/~/products", "read"); yield assertExistenceInUserPermissions(userB, { accessLevel: "read", path: `/${userA.identity}/products`, }); })); }); }); describe("Admin token user", () => { let userA; let adminTokenUser; beforeEach(() => __awaiter(this, void 0, void 0, function* () { userA = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const token = Token_1.generateAdminToken({ privateKey: server.privateKey, }); const adminCredentials = realmUtil_1.Realm.Sync.Credentials.adminToken(token); adminTokenUser = realmUtil_1.Realm.Sync.User.login(server.url, adminCredentials); yield openRealm({ sync: { user: userA, url: `realm://${server.address}/~/products` }, schema: [Product.ProductSchema] }); })); describe("adminTokenUser granting write to all for userA's realm", () => { it("should generate a wildcard permission", () => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(adminTokenUser, { userId: "*" }, `/${userA.identity}/products`, "write"); yield assertExistenceInUserPermissions(userB, { accessLevel: "write", path: `/${userA.identity}/products` }); })); }); }); describe("offers", () => { describe("with an invalid user in the path", () => { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const token = Token_1.generateAdminToken({ privateKey: server.privateKey, }); const adminCredentials = realmUtil_1.Realm.Sync.Credentials.adminToken(token); const tokenUser = realmUtil_1.Realm.Sync.User.login(server.url, adminCredentials); yield chai_1.assert.isRejected(offerPermissions(tokenUser, "/__auth/products", "read"), "Your request parameters did not validate."); })); }); describe("userA offers read permission to Realm that doesn't exist", () => { it("should fail", () => __awaiter(this, void 0, void 0, function* () { const error = yield chai_1.assert.isRejected(offerPermissions(userA, "/~/products-no-exist", "read"), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); }); describe("userA offers read permissions to a Realm without manage access", () => { it("should fail", () => __awaiter(this, void 0, void 0, function* () { yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/~/products`, user: userB, }, schema: [Product.ProductSchema] })); const error = yield chai_1.assert.isRejected(offerPermissions(userA, `/${userB.identity}/products`, "read"), "The path is invalid or current user has no access."); chai_1.assert.equal(error.statusCode, 614); })); }); describe("userA offers read permissions", () => { let token; beforeEach(() => __awaiter(this, void 0, void 0, function* () { token = yield offerPermissions(userA, "/~/products", "read"); })); describe("userB accepts permission offer", () => { let offeredPath; beforeEach(() => __awaiter(this, void 0, void 0, function* () { offeredPath = (yield chai_1.assert.isFulfilled(acceptPermissionOffer(userB, token))); })); it("should be successful", () => __awaiter(this, void 0, void 0, function* () { chai_1.assert.equal(offeredPath, `/${userA.identity}/products`); yield assertUserPermissions(userA, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); yield assertUserPermissions(userB, { userId: userB.identity, accessLevel: "read", path: `/${userA.identity}/products` }); const realm = yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}${offeredPath}`, user: userB, }, })); const p = realm.objects("Product")[0]; chai_1.assert.equal(p.productId, realmAProduct.productId); chai_1.assert.equal(p.name, realmAProduct.name); chai_1.assert.equal(p.price, realmAProduct.price); realm.write(() => { realm.create("Product", { productId: 1, name: faker.commerce.productName(), price: faker.random.number({ min: 12, max: 7000 }) }); }); realm.close(); })); it("userB should not be able to offer permissions to it (no manage)", () => __awaiter(this, void 0, void 0, function* () { const error = yield chai_1.assert.isRejected(offerPermissions(userB, `/${userA.identity}/products`, "read"), "The path is invalid or current user has no access."); chai_1.assert.equal(error.statusCode, 614); })); }); describe("userA then invalidates the offer", () => { beforeEach(() => __awaiter(this, void 0, void 0, function* () { yield invalidatePermissionOffer(userA, token); })); it("userB should not be able to accept the offer", () => __awaiter(this, void 0, void 0, function* () { yield chai_1.assert.isRejected(acceptPermissionOffer(userB, token), "The permission offer is expired."); const error = yield chai_1.assert.isRejected(openRealm({ sync: { url: `realm://${server.address}/${userA.identity}/products`, user: userB, }, schema: [Product.ProductSchema] }), "The path is invalid or current user has no access."); chai_1.assert.equal(error.status, 403); chai_1.assert.equal(error.code, 614); })); }); }); describe("userA offers redundant permissions to administrator", () => __awaiter(this, void 0, void 0, function* () { beforeEach(() => __awaiter(this, void 0, void 0, function* () { yield applyPermissions(userA, { userId: userB.identity }, "/~/products", "admin"); yield assertExistenceInUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: `/${userA.identity}/products` }); })); it("should not remove admin status if offered a write permission", () => __awaiter(this, void 0, void 0, function* () { const token = yield offerPermissions(userA, "/~/products", "write"); const offeredPath = yield chai_1.assert.isFulfilled(acceptPermissionOffer(userB, token)); yield assertUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: offeredPath }); })); it("should not remove admin status if offered a read permission", () => __awaiter(this, void 0, void 0, function* () { const token = yield offerPermissions(userA, "/~/products", "read"); const offeredPath = yield chai_1.assert.isFulfilled(acceptPermissionOffer(userB, token)); yield assertUserPermissions(userB, { userId: userB.identity, accessLevel: "admin", path: offeredPath }); })); })); describe("userA offers expired permissions to userB", () => __awaiter(this, void 0, void 0, function* () { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const expiresAt = new Date(); const error = yield chai_1.assert.isRejected(offerPermissions(userA, "/~/products", "write", expiresAt), "The permission offer is expired."); chai_1.assert.equal(error.statusCode, 701); })); })); describe("userB accepts expired permission offer from userA", () => __awaiter(this, void 0, void 0, function* () { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const expiresAt = new Date(); expiresAt.setSeconds(expiresAt.getSeconds() + 1); const token = yield offerPermissions(userA, "/~/products", "write", expiresAt); yield new Promise((resolve) => setTimeout(resolve, 1000)); const error = yield chai_1.assert.isRejected(acceptPermissionOffer(userB, token), "The permission offer is expired."); chai_1.assert.equal(error.statusCode, 701); })); })); describe("userB accepts expired permission offer with invalid token", () => __awaiter(this, void 0, void 0, function* () { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { const token = "INVALID TOKEN"; const error = yield chai_1.assert.isRejected(acceptPermissionOffer(userB, token), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); })); describe("userB accepts expired permission offer with invalid token", () => __awaiter(this, void 0, void 0, function* () { it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () { yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const token = "INVALID TOKEN"; const error = yield chai_1.assert.isRejected(acceptPermissionOffer(userB, token), "Your request parameters did not validate."); chai_1.assert.equal(error.statusCode, 601); })); })); }); }); describe("Partial sync with other user's Realm", () => { it("Opening the partial Realm should succeed", () => __awaiter(this, void 0, void 0, function* () { const user1 = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const user2 = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${user1.identity}/product`, user: user1, fullSynchronization: false }, schema: [Product.ProductSchema] })); yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/${user1.identity}/product`, user: user2, fullSynchronization: false }, schema: [Product.ProductSchema] })); })); it("Opening the partial Realm with incorrect prefix should fail", () => __awaiter(this, void 0, void 0, function* () { const user = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const bad_prefix = `abc${user.identity}`; const error = yield chai_1.assert.isRejected(openRealm({ sync: { url: `realm://${server.address}/${bad_prefix}/product`, user: user, fullSynchronization: false }, schema: [Product.ProductSchema] }), ""); chai_1.assert.equal(error.name, "AuthError"); })); }); describe("Default Realm", () => { it("admin user should be able to perform partial sync with the default Realm", () => __awaiter(this, void 0, void 0, function* () { const adminUser = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/default`, user: adminUser, fullSynchronization: false }, schema: [Product.ProductSchema] })); })); it("non-admin user should be able to perform partial sync with the default Realm", () => __awaiter(this, void 0, void 0, function* () { const user = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); yield chai_1.assert.isFulfilled(openRealm({ sync: { url: `realm://${server.address}/default`, user: user, fullSynchronization: false }, schema: [Product.ProductSchema] })); })); }); describe.skip("User deletion", () => { let userNameA; let passwordA; let userIdA; let adminUser; beforeEach(() => __awaiter(this, void 0, void 0, function* () { userNameA = uuid.v4(); passwordA = faker.internet.password(); const credentials = realmUtil_1.Realm.Sync.Credentials.usernamePassword(userNameA, passwordA); const userA = yield realmUtil_1.Realm.Sync.User.login(server.url, credentials); userIdA = userA.identity; adminUser = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); const realmA = yield openRealm({ sync: { user: userA, url: `realm://${server.address}/~/products` }, schema: [Product.ProductSchema] }); realmA.write(() => { realmA.create("Product", { productId: 0, name: faker.commerce.productName(), price: faker.random.number({ min: 12, max: 7000 }) }); }); const uploadCompletion = new Promise((resolve, reject) => { realmA.syncSession.addProgressNotification("upload", "forCurrentlyOutstandingWork", (uploaded, uploadable) => { if (uploaded === uploadable) { resolve(); } }); }); yield uploadCompletion; realmA.close(); })); it("UserA can login", () => __awaiter(this, void 0, void 0, function* () { const credentials = realmUtil_1.Realm.Sync.Credentials.usernamePassword(userNameA, passwordA, false); const user = yield realmUtil_1.Realm.Sync.User.login(server.url, credentials); chai_1.assert.strictEqual(user.identity, userIdA, "The user name must be the same"); })); it("UserA cannot login after being deleted", () => __awaiter(this, void 0, void 0, function* () { yield superagent.delete(`${server.url}/auth/user/${userIdA}`).set({ Authorization: adminUser.token, }) .send(); const credentials = realmUtil_1.Realm.Sync.Credentials.usernamePassword(userNameA, passwordA, false); const userPromise = realmUtil_1.Realm.Sync.User.login(server.url, credentials); yield chai_1.assert.isRejected(userPromise); })); it("adminUser reads UserA's Realm without deleting UserA", () => __awaiter(this, void 0, void 0, function* () { const config = { sync: { user: adminUser, url: `realm://${server.address}/${userIdA}/products` }, schema: [Product.ProductSchema] }; const realm = yield openRealm(config); const products = realm.objects("Product"); chai_1.assert.strictEqual(products.length, 1); realm.close(); })); it("adminUser reads UserA's Realm after deleting UserA", () => __awaiter(this, void 0, void 0, function* () { yield superagent.delete(`${server.url}/auth/user/${userIdA}`).set({ Authorization: adminUser.token, }) .send(); const config = { sync: { user: adminUser, url: `realm://${server.address}/${userIdA}/products` }, schema: [Product.ProductSchema] }; const realm = yield openRealm(config); const products = realm.objects("Product"); chai_1.assert.strictEqual(products.length, 0); realm.close(); })); }); describe("Realm deletion", () => { let userIdA; let adminUser; beforeEach(() => __awaiter(this, void 0, void 0, function* () { const userA = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); chai_1.assert.notStrictEqual(userIdA, userA.identity); userIdA = userA.identity; adminUser = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); const realmA = yield openRealm({ sync: { user: userA, url: `realm://${server.address}/~/products` }, schema: [Product.ProductSchema] }); realmA.write(() => { realmA.create("Product", { productId: 0, name: faker.commerce.productName(), price: faker.random.number({ min: 12, max: 7000 }) }); }); const uploadCompletion = new Promise((resolve, reject) => { realmA.syncSession.addProgressNotification("upload", "forCurrentlyOutstandingWork", (uploaded, uploadable) => { if (uploaded === uploadable) { resolve(); } }); }); yield uploadCompletion; realmA.close(); })); it("adminUser reads the product Realm with no Realm deletion", () => __awaiter(this, void 0, void 0, function* () { const config = { sync: { user: adminUser, url: `realm://${server.address}/${userIdA}/products` }, schema: [Product.ProductSchema] }; const realm = yield openRealm(config); const products = realm.objects("Product"); chai_1.assert.strictEqual(products.length, 1); realm.close(); })); it("adminUser reads UserA's Realm after deleting UserA", () => __awaiter(this, void 0, void 0, function* () { const deleteUrl = new URI(server.url).segment(["realms", "files"]).segmentCoded(`${userIdA}/products`).toString(); yield superagent.delete(deleteUrl).set({ Authorization: adminUser.token, }) .send(); const config = { sync: { user: adminUser, url: `realm://${server.address}/${userIdA}/products` }, schema: [Product.ProductSchema] }; const realm = yield openRealm(config); const products = realm.objects("Product"); chai_1.assert.strictEqual(products.length, 0); realm.close(); })); }); describe("Realm name case sensitivity", () => { describe("opening a Realm with different casing", () => { it("should not crash ROS", function () { return __awaiter(this, void 0, void 0, function* () { this.timeout(100000); const user = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.anonymous()); const realmA = yield openRealm({ sync: { user, url: `realm://${server.address}/~/products`, }, schema: [Product.ProductSchema] }); realmA.write(() => { realmA.create("Product", { name: "123", price: 123, productId: 123 }); }); yield realmA.syncSession.uploadAllLocalChanges(); realmA.close(); const error = yield chai_1.assert.isRejected(openRealm({ sync: { user, url: `realm://${server.address}/~/pRoDuCtS`, }, schema: [Product.ProductSchema] })); chai_1.assert.equal(error.status, 400); chai_1.assert.equal(error.code, 601); chai_1.assert.equal(error.invalid_params.length, 1); const param = error.invalid_params[0]; chai_1.assert.equal(param.name, "realmPath"); chai_1.assert.include(param.reason, "/pRoDuCtS"); chai_1.assert.include(param.reason, "/products"); const admin = yield realmUtil_1.Realm.Sync.User.login(server.url, realmUtil_1.Realm.Sync.Credentials.usernamePassword("realm-admin", "")); const adminRealm = yield openRealm({ sync: { user: admin, url: `realm://${server.address}/__admin` } }); chai_1.assert.isNotOk(adminRealm.objectForPrimaryKey("RealmFile", `/${user.identity}/pRoDuCtS`)); chai_1.assert.isOk(adminRealm.objectForPrimaryKey("RealmFile", `/${user.identity}/products`)); }); }); }); }); }); //# sourceMappin