Code snippets for a tutorial on building a video app with JaaS, React and Vercel
Last active
July 9, 2021 21:35
-
-
Save chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ALLOW_LIST='walter@gooddogs.com,scout@gooddogs.com' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ALLOW_LIST= | |
JAAS_ROOM_NAME= | |
JAAS_APP_ID= | |
JAAS_KEY_ID= | |
JAAS_PRIVATE_KEY= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
JAAS_ROOM_NAME=AllAboutThatJAAS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cat {Key Name}.pk | base64 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rm ./src/App.css ./src/index.css ./src/logo.svg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npx create-react-app jaas-hands | |
cd jaas-hands | |
npm start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm install bootstrap bootstrap-react uuid jsonwebtoken |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm install --global vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mkdir ./api |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vercel dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
touch ./api/join.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vercel deploy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const generateAvatar = (email) => { | |
const hash = crypto.createHash('md5').update(email).digest("hex"); | |
return 'https://www.gravatar.com/avatar/' + hash; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JWT Generator -- Takes user's name and email address | |
const generateJWT = (name, email, roomName) => { | |
// Configure the JWT Header | |
const key = process.env.JAAS_KEY_ID; | |
const header = { algorithm: 'RS256', keyid: key }; | |
// Get the current time and set the time boundaries of the JWT | |
const now = new Date(); | |
const expiration = Math.round(now.setHours(now.getHours() + 3) / 1000); | |
const notBefore = (Math.round((new Date).getTime() / 1000) - 10); | |
// Build the JWT Payload | |
const avatar = generateAvatar(email); | |
const id = uuid(); | |
const payload = { | |
aud: 'jitsi', | |
context: { | |
user: { | |
id, | |
name, | |
avatar, | |
email: email, | |
moderator: 'true' | |
}, | |
features: { | |
livestreaming: 'true', | |
recording: 'true', | |
transcription: 'true', | |
"outbound-call": 'true' | |
} | |
}, | |
iss: 'chat', | |
room: '*', | |
sub: process.env.JAAS_APP_ID, | |
exp: expiration, | |
nbf: notBefore | |
}; | |
// Load and decode the Private Key from the ENV | |
let buff = Buffer.from(process.env.JAAS_PRIVATE_KEY, 'base64'); | |
const privateKey = buff.toString('ascii') | |
// Finally, sign the JWT | |
return jsonwebtoken.sign( | |
payload, | |
privateKey, | |
header | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const isAllowed = (email) => { | |
const friendsList = process.env.ALLOW_LIST.split(','); | |
return (friendsList.indexOf(email) >= 0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var jsonwebtoken = require('jsonwebtoken'); | |
var uuid = require('uuid-random'); | |
var crypto = require('crypto'); | |
// Helper function to generate an avatar with the help of Gravatar | |
const generateAvatar = (email) => { | |
const hash = crypto.createHash('md5').update(email).digest("hex"); | |
return 'https://www.gravatar.com/avatar/' + hash; | |
} | |
// Our super secure Access Management System :) | |
const isAllowed = (email) => { | |
const friendsList = process.env.ALLOW_LIST.split(','); | |
return (friendsList.indexOf(email) >= 0); | |
} | |
// Generate a Room Name | |
const generateRoomName = () => { | |
return process.env.JAAS_APP_ID + '/' + process.env.JAAS_ROOM_NAME; | |
} | |
// JWT Generator -- Takes user's name and email address | |
const generateJWT = (name, email, roomName) => { | |
// Configure the JWT Header | |
const key = process.env.JAAS_KEY_ID; | |
const header = { algorithm: 'RS256', keyid: key }; | |
// Get the current time and set the time boundaries of the JWT | |
const now = new Date(); | |
const expiration = Math.round(now.setHours(now.getHours() + 3) / 1000); | |
const notBefore = (Math.round((new Date).getTime() / 1000) - 10); | |
// Build the JWT Payload | |
const avatar = generateAvatar(email); | |
const id = uuid(); | |
const payload = { | |
aud: 'jitsi', | |
context: { | |
user: { | |
id, | |
name, | |
avatar, | |
email: email, | |
moderator: 'true' | |
}, | |
features: { | |
livestreaming: 'true', | |
recording: 'true', | |
transcription: 'true', | |
"outbound-call": 'true' | |
} | |
}, | |
iss: 'chat', | |
room: '*', | |
sub: process.env.JAAS_APP_ID, | |
exp: expiration, | |
nbf: notBefore | |
}; | |
// Load and decode the Private Key from the ENV | |
let buff = Buffer.from(process.env.JAAS_PRIVATE_KEY, 'base64'); | |
const privateKey = buff.toString('ascii') | |
// Finally, sign the JWT | |
return jsonwebtoken.sign( | |
payload, | |
privateKey, | |
header | |
); | |
} | |
// Request Handler | |
export default async (req, res) => { | |
// Parse the JSON request | |
const { body } = req; | |
const email = body.email.trim().toLowerCase(); | |
const roomName = generateRoomName(); | |
// Construct our default response payload | |
res.statusCode = 403; | |
const payload = { | |
email: body.email, | |
success: false | |
}; | |
// Check to see if the user is allowed, if so make them a JWT. | |
if (isAllowed(body.email)) { | |
payload.key = generateJWT(email, email, roomName); | |
payload.room = roomName; | |
payload.success = true; | |
res.statusCode = 200; | |
} | |
// Construct Response | |
res.setHeader("Content-Type", "application/json"); | |
res.send(JSON.stringify(payload)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Request Handler | |
export default async (req, res) => { | |
// Parse the JSON request | |
const { body } = req; | |
const email = body.email.trim().toLowerCase(); | |
const roomName = generateRoomName(); | |
// Construct our default response payload | |
res.statusCode = 403; | |
const payload = { | |
email: body.email, | |
success: false | |
}; | |
// Check to see if the user is allowed, if so make them a JWT. | |
if (isAllowed(body.email)) { | |
payload.key = generateJWT(email, email, roomName); | |
payload.room = roomName; | |
payload.success = true; | |
res.statusCode = 200; | |
} | |
// Construct Response | |
res.setHeader("Content-Type", "application/json"); | |
res.send(JSON.stringify(payload)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Container, Form, Button } from "react-bootstrap"; | |
function App() { | |
return ( | |
<div className="App"> | |
<Container> | |
<h2>Lets JaaS It Up</h2> | |
<Form | |
style={{ display: allowed ? "none" : "block" }}> | |
<Form.Group> | |
<Form.Label htmlFor="email"> | |
Email Address | |
</Form.Label> | |
<Form.Control | |
value={email} | |
onChange={(e) => setEmail(e.target.value)} /> | |
</Form.Group> | |
<Button variant="primary" type="submit">Join</Button> | |
</Form> | |
<div style={{ display: allowed ? "block" : "none" }}> | |
<div id="jaas-container" style={{height: "700px"}}></div> | |
</div> | |
</Container> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from "react"; | |
import { Container, Form, Button } from "react-bootstrap"; | |
function App() { | |
// Setup our Hooks to manage state | |
const [email, setEmail] = useState(""); | |
const [allowed, setAllowed] = useState(false); | |
return ( | |
<div className="App"> | |
<Container> | |
<h2>Lets JaaS It Up</h2> | |
<Form | |
style={{ display: allowed ? "none" : "block" }}> | |
<Form.Group> | |
<Form.Label htmlFor="email"> | |
Email Address | |
</Form.Label> | |
<Form.Control | |
value={email} | |
onChange={(e) => setEmail(e.target.value)} /> | |
</Form.Group> | |
<Button variant="primary" type="submit">Join</Button> | |
</Form> | |
<div style={{ display: allowed ? "block" : "none" }}> | |
<div id="jaas-container" style={{height: "700px"}}></div> | |
</div> | |
</Container> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'bootstrap/dist/css/bootstrap.min.css'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Setup our Hooks to manage state | |
const [email, setEmail] = useState(""); | |
const [allowed, setAllowed] = useState(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Form onSubmit={onSubmit} style={{ display: allowed ? "none" : "block" }}> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
const script = document.createElement('script'); | |
script.src = "https://8x8.vc/external_api.js"; | |
script.async = true; | |
document.body.appendChild(script); | |
return () => { | |
document.body.removeChild(script); | |
} | |
}, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Handle the user submission | |
const onSubmit = async (e) => { | |
await e.preventDefault(); | |
const res = await fetch("/api/join", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify({email: email}) | |
}); | |
const data = await res.json(); | |
if(data.success) { | |
setAllowed(data.success); | |
setTimeout(() => { initJaas(data); }, 500 ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Init the JaaS iFrame API once we have a JWT | |
const initJaas = (data) => { | |
new JitsiMeetExternalAPI("8x8.vc", { | |
roomName: data.room, | |
parentNode: document.querySelector('#jaas-container'), | |
jwt: data.key | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment