Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show new participants as they join #407

Merged
merged 61 commits into from
Apr 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
5a94759
Test for WebSockets on the roster page
douglasnaphas Mar 18, 2022
0ce5876
Add a WebSockets API behind CloudFront
douglasnaphas Mar 19, 2022
f8ac33c
Grant the WS handlers RW access to the Table
douglasnaphas Mar 19, 2022
c97f321
Use a variable URL on the Explain Page
douglasnaphas Mar 19, 2022
7f3d88f
Fix relative import of schema
douglasnaphas Mar 19, 2022
a3e1da1
Remove bizarre commas from variable in JSX
douglasnaphas Mar 19, 2022
01905c6
Include cookies and query params in WS requests
douglasnaphas Mar 19, 2022
22ac283
Stream table changes to trigger.js
douglasnaphas Mar 19, 2022
ae67a7e
Remove dead reference from trigger.js
douglasnaphas Mar 19, 2022
37d8543
Move resource creation out of the handler
douglasnaphas Mar 20, 2022
5be0b29
Log WS_ENDPOINT in initialization and handler
douglasnaphas Mar 20, 2022
fc7953d
Remove experiment on env during initialization
douglasnaphas Mar 20, 2022
93258ef
Try filter for only participant events
douglasnaphas Mar 20, 2022
3fa17c2
Move event filter to separate file, all one line
douglasnaphas Mar 20, 2022
7fc2374
Let the joinedHandler read the stream
douglasnaphas Mar 20, 2022
f023d0f
Do stringified logging with the old handler
douglasnaphas Mar 20, 2022
2e297b2
Delete the mapping so I can re-create it
douglasnaphas Mar 20, 2022
8002f88
Re-create the joinedHandler with better logging
douglasnaphas Mar 20, 2022
eae831f
Rename joinedHandler to streamHandler
douglasnaphas Mar 20, 2022
a3a93b4
Rename joined handler JS file
douglasnaphas Mar 20, 2022
00d2fea
Try to detect joins
douglasnaphas Mar 23, 2022
332199a
Add logging to stream handler, why no joins?
douglasnaphas Mar 23, 2022
667310d
Remember the S after lib_id
douglasnaphas Mar 23, 2022
8965e84
Add tests and no-op WS to Roster
douglasnaphas Mar 24, 2022
cf9bf99
Connect to the WS on RosterPage load
douglasnaphas Mar 24, 2022
3007a9d
Use decodeURIComponent, not just decodeURI
douglasnaphas Mar 24, 2022
bea1811
Use encodeURIComponent, not just encodeURI
douglasnaphas Mar 24, 2022
e62082e
Convert Dynamo SDK to import, not require
douglasnaphas Mar 25, 2022
9d8e704
Add a placeholder test for connect.js
douglasnaphas Mar 25, 2022
4c75a8d
Actually mock an AWS SDK call, I think
douglasnaphas Mar 25, 2022
e798bd0
Actually return something from mocked get
douglasnaphas Mar 25, 2022
325e5b0
Test some more cases, connect.js
douglasnaphas Mar 25, 2022
c63eb44
Implement connect.js with tests
douglasnaphas Mar 26, 2022
590cb9d
Remove secondary color for "get script anyway"
douglasnaphas Mar 26, 2022
f366cef
Remove unused accidental import
douglasnaphas Mar 26, 2022
3110e65
Use logger in stream.js
douglasnaphas Mar 26, 2022
651fba4
Set up test template for stream
douglasnaphas Mar 26, 2022
b5097f2
Add a test for multiple game cookies
douglasnaphas Mar 26, 2022
a87f4d9
Handle multiple game cookies
douglasnaphas Mar 26, 2022
995134f
Log the gameNameHash
douglasnaphas Mar 26, 2022
d064300
Add a test for space after semicolon
douglasnaphas Mar 26, 2022
fdc4247
Handle space after semicolor in Cookie header
douglasnaphas Mar 26, 2022
a094956
Message the room about new participant joins
douglasnaphas Mar 27, 2022
214b76c
Log the query error I'm currently getting
douglasnaphas Mar 27, 2022
2a41662
Identify happy path 1 case
douglasnaphas Mar 27, 2022
c07966f
Log the db query params as well, for debugging
douglasnaphas Mar 27, 2022
f6564b8
Let the stream handler post to the WSAPI
douglasnaphas Mar 27, 2022
cad47a6
Let the stream handler query the DB
douglasnaphas Mar 27, 2022
4df7759
Format the WSAPI property for API call
douglasnaphas Mar 27, 2022
feccbd7
Try harder to trim wss:// from the endpoint
douglasnaphas Mar 27, 2022
6874640
Construct the WS API from its ID
douglasnaphas Mar 27, 2022
f278611
Remove unused testing-library imports
douglasnaphas Mar 27, 2022
b101246
Contain WS activity within one page at a time
douglasnaphas Mar 27, 2022
c554963
Merge new participants into roster
douglasnaphas Mar 28, 2022
4a5238e
Wrap the newParticipant in an object
douglasnaphas Mar 28, 2022
ee72295
Deserialize newParticipant on the front end
douglasnaphas Mar 28, 2022
d439266
Don't display duplicate new participants
douglasnaphas Mar 28, 2022
6f2ecfa
Sort participants case-insensitively in roster
douglasnaphas Mar 29, 2022
78fca98
Format sortParticipants.js
douglasnaphas Mar 29, 2022
d3bcd1c
Insert new participant in sorted order (front-end)
douglasnaphas Mar 29, 2022
089d737
Fix the name of the disconnect handler
douglasnaphas Mar 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
!frontend/**/*.js
!backend/*.js
!backend/**/*.js
!eventFilters/*.js
!eventFilters/**/*.js
!itest/*.js
!itest/**/*.js
!content/*.js
Expand Down
99 changes: 99 additions & 0 deletions backend/connect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const DynamoDB = require("aws-sdk/clients/dynamodb");
const schema = require("./schema");
const db = new DynamoDB.DocumentClient();
const crypto = require("crypto");
const logger = require("./logger");

exports.handler = async function (event, context, callback) {
logger.log("connect handler called");
logger.log("event:");
logger.log(JSON.stringify(event));
logger.log("context:");
logger.log(JSON.stringify(context));

// validate the connection request
if (
!event ||
!event.queryStringParameters ||
!event.queryStringParameters.roomcode ||
!event.queryStringParameters.gamename
) {
logger.log("missing queryStringParameters");
return { statusCode: 400, body: "Bad request" };
}

const roomCode = event.queryStringParameters.roomcode;
const gameName = decodeURIComponent(event.queryStringParameters.gamename);
const hash = crypto.createHash("sha256");
hash.update(gameName);
const GAME_NAME_HASH_LENGTH = 64;
const gameNameHash = hash
.digest("hex")
.substring(0, GAME_NAME_HASH_LENGTH)
.toLowerCase();
if (!event.multiValueHeaders || !event.multiValueHeaders.Cookie) {
logger.log("no cookies");
return { statusCode: 400, body: "Bad request" };
}
logger.log("gameNameHash:");
logger.log(gameNameHash);
const gameCookie = event.headers.Cookie.split(";")
.map((cookie) => cookie.trim())
.find((cookie) => new RegExp(`^${gameNameHash}=.`).test(cookie));
const RIGHT_HAND_SIDE = 1;
const cookieSessionKey = gameCookie.split("=")[RIGHT_HAND_SIDE];
if (!gameCookie || !cookieSessionKey) {
logger.log("no cookie with the right name, looking for " + gameNameHash);
return { statusCode: 400, body: "Bad request" };
}
const getParticipantParams = {
TableName: process.env.TABLE_NAME,
Key: {
[schema.PARTITION_KEY]: roomCode,
[schema.SORT_KEY]:
`${schema.PARTICIPANT_PREFIX}` +
`${schema.SEPARATOR}` +
`${gameNameHash}`,
},
};
try {
const participantData = await db.get(getParticipantParams).promise();
if (participantData.Item[schema.SESSION_KEY] != cookieSessionKey) {
logger.log("session key mismatch");
return { statusCode: 400, body: "Bad request" };
}
} catch (e) {
logger.log("error getting participant data", e);
return { statusCode: 500, body: "Server error" };
}

const now = new Date();
var putParams = {
TableName: process.env.TABLE_NAME,
Item: {
[schema.PARTITION_KEY]: `${roomCode}`,
[schema.SORT_KEY]:
`${schema.CONNECT}` +
`${schema.SEPARATOR}` +
`${event.requestContext.connectionId}`,
[schema.CONNECTION_ID]: event.requestContext.connectionId,
[schema.DATE]: now.toISOString(),
[schema.MS]: now.getTime(),
},
};

try {
await db.put(putParams).promise();
return {
statusCode: 200,
body: "Connected",
};
} catch (e) {
logger.log("error on put");
logger.log(e);
return {
statusCode: 500,
body: "Server error",
};
}
};
Loading