Skip to content

Commit 1dd65f9

Browse files
wrjgoldRichDom2185
andauthored
Feat/session readonly (#25)
* updated backend to incorporate read only sessions * updated backend to incorporate readonly session * fixed bug in getSessionDetails function * updated backend with shorter ids for generated sessions * Removed console.log and added extra layer of readonly check on backend * changed document implementation to Map to support sublinear lookup. Added checking of shortIds generated to prevent repeat * Add empty line at end-of-file * Fix format * Restore empty line --------- Co-authored-by: Richard Dominick <[email protected]>
1 parent abb5be8 commit 1dd65f9

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

index.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,47 +12,59 @@ const app = new Koa();
1212
const db = new ShareDB();
1313

1414
db.use('connect', (ctx, done) => {
15-
// use custom to store the allowed document ID
15+
// use custom to store the allowed document ID and readOnly setting
1616
ctx.agent.custom = ctx.req;
1717
done();
1818
});
1919
db.use('submit', (ctx, done) => {
20-
const allowed = ctx.collection === COLLECTION_NAME && ctx.id === ctx.agent.custom;
20+
const allowed =
21+
ctx.collection === COLLECTION_NAME &&
22+
ctx.id === ctx.agent.custom.docId &&
23+
!ctx.agent.custom.readOnly;
2124
done(allowed ? undefined : 'Cannot write to this document');
2225
});
2326
db.use('readSnapshots', (ctx, done) => {
2427
const allowed =
2528
ctx.collection === COLLECTION_NAME &&
26-
!ctx.snapshots.find((snapshot) => snapshot.id !== ctx.agent.custom);
29+
!ctx.snapshots.find((snapshot) => snapshot.id !== ctx.agent.custom.docId);
2730
done(allowed ? undefined : 'Cannot read these document(s)');
2831
});
2932

30-
const documents = new Set();
33+
const documents = new Map();
3134

3235
app.use(cors());
3336
app.use(websocket());
3437
app.use(bodyParser({ enableTypes: ['json', 'text'], strict: false }));
3538
app.use(async (ctx) => {
3639
if (ctx.method === 'POST' && ctx.path === '/') {
37-
const contents = isEmptyObject(ctx.request.body) ? '' : ctx.request.body;
40+
const { contents } = ctx.request.body;
41+
42+
// Creates various IDs
3843
const docId = uuid();
39-
const doc = db.connect(undefined, docId).get(COLLECTION_NAME, docId);
44+
const sessionEditingId = generateShortId();
45+
documents.set(sessionEditingId, [docId, false]);
46+
const sessionViewingId = generateShortId();
47+
documents.set(sessionViewingId, [docId, true]);
48+
49+
const connection = db.connect(undefined, { docId, readOnly: false });
50+
const doc = connection.get(COLLECTION_NAME, docId);
4051
await new Promise((resolve, reject) => {
41-
doc.create(contents, (err) => {
52+
doc.create({ contents }, (err) => {
4253
if (err) {
4354
reject(err);
4455
} else {
4556
resolve();
4657
}
4758
});
4859
});
49-
documents.add(docId);
50-
ctx.body = docId;
60+
ctx.body = { docId, sessionEditingId, sessionViewingId };
5161
return;
5262
}
5363

54-
const docId = ctx.path.substr(1);
55-
if (!documents.has(docId)) {
64+
const sessionId = ctx.path.substr(1);
65+
const [docId, readOnly] = getSessionDetails(sessionId);
66+
67+
if (docId === null) {
5668
ctx.status = 404;
5769
return;
5870
}
@@ -64,14 +76,24 @@ app.use(async (ctx) => {
6476

6577
if (ctx.ws) {
6678
const ws = new WebSocketJSONStream(await ctx.ws());
67-
db.listen(ws, docId);
79+
db.listen(ws, { docId, readOnly }); // docId and readOnly is passed to 'connect' middleware as ctx.req
6880
} else {
69-
ctx.body = 'Document exists.';
81+
ctx.body = { docId, readOnly };
7082
}
7183
});
7284

7385
app.listen(process.env.PORT || 8080);
7486

75-
function isEmptyObject(obj) {
76-
return Object.keys(obj).length === 0 && obj.constructor === Object;
87+
function getSessionDetails(sessionId) {
88+
const sessionDetails = documents.get(sessionId);
89+
return sessionDetails === undefined ? [null, null] : sessionDetails;
90+
}
91+
92+
function generateShortId() {
93+
const id = uuid().slice(0, 6);
94+
if (documents.has(id)) {
95+
return generateShortId();
96+
} else {
97+
return id;
98+
}
7799
}

0 commit comments

Comments
 (0)