realm-object-server
Version:
962 lines • 50 kB
JavaScript
"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