Skip to content

Commit

Permalink
feat: Jaas example that uses local jitsi-meet (jitsi#13350)
Browse files Browse the repository at this point in the history
* feat: Adds an example to convert a deployment to use jaas.

* squash: Generates the daily asap token with expiration of 1 day.

The default is 1 hour.

* squash: Use local deployment UI with jaas, not 8x8.vc one.

- We load config.js from 8x8.vc with the tenant, to allow release pinning to work.

- We sed the vpass_cookie in the custom nginx conf as variables are not allowed in location matching.

- The jaas-vars need to be global as it will overwrite config.js location and index html.

* squash: Enables e2ee for the meetings.

* squash: Bump node version check.

* squash: Fix filename.

* squash: Updates the readme.

* squash: Checks whether node is installed.

* squash: Fixes initial configuration.

The jaas-vars is required to reload nginx, done by update-asap-daily script.

* squash: More fixes of misspelled config file.

* squash: Fixes serving the pub key.
  • Loading branch information
damencho authored May 15, 2023
1 parent f76122f commit d8c7f8d
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# The build artifacts of the jitsi-meet project.
build/*

doc/*

# Third-party source code which we (1) do not want to modify or (2) try to
# modify as little as possible.
libs/*
Expand Down
3 changes: 3 additions & 0 deletions debian/jitsi-meet-web-config.install
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
doc/debian/jitsi-meet/jitsi-meet.example /usr/share/jitsi-meet-web-config/
doc/debian/jitsi-meet/jitsi-meet.example-apache /usr/share/jitsi-meet-web-config/
config.js /usr/share/jitsi-meet-web-config/
doc/jaas/nginx-jaas.conf /usr/share/jitsi-meet-web-config/
doc/jaas/index-jaas.html /usr/share/jitsi-meet-web-config/
doc/jaas/8x8.vc-config.js /usr/share/jitsi-meet-web-config/
2 changes: 2 additions & 0 deletions debian/jitsi-meet-web.install
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ resources/robots.txt /usr/share/jitsi-meet/
resources/*.sh /usr/share/jitsi-meet/scripts/
pwa-worker.js /usr/share/jitsi-meet/
manifest.json /usr/share/jitsi-meet/
doc/jaas/move-to-jaas.sh /usr/share/jitsi-meet/scripts/
doc/jaas/update-asap-daily.sh /usr/share/jitsi-meet/scripts/
16 changes: 13 additions & 3 deletions doc/debian/jitsi-meet/jitsi-meet.example
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ server {

add_header Strict-Transport-Security "max-age=63072000" always;
set $prefix "";
set $custom_index "";
set $config_js_location /etc/jitsi/meet/jitsi-meet.example.com-config.js;

ssl_certificate /etc/jitsi/meet/jitsi-meet.example.com.crt;
ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;
Expand All @@ -77,8 +79,10 @@ server {
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 512;

include /etc/jitsi/meet/jaas/*.conf;

location = /config.js {
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
alias $config_js_location;
}

location = /external_api.js {
Expand All @@ -92,6 +96,11 @@ server {
proxy_set_header Host $http_host;
}

location ~ ^/_api/public/(.*)$ {
autoindex off;
alias /etc/jitsi/meet/public/$1;
}

# ensure all static content can always be found first
location ~ ^/(libs|css|static|images|fonts|lang|sounds|.well-known)/(.*)$
{
Expand Down Expand Up @@ -142,19 +151,20 @@ server {
#}

location ~ ^/([^/?&:'"]+)$ {
set $roomname "$1";
try_files $uri @root_path;
}

location @root_path {
rewrite ^/(.*)$ / break;
rewrite ^/(.*)$ /$custom_index break;
}

location ~ ^/([^/?&:'"]+)/config.js$
{
set $subdomain "$1.";
set $subdir "$1/";

alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
alias $config_js_location;
}

# Matches /(TENANT)/pwa-worker.js or /(TENANT)/manifest.json to rewrite to / and look for file
Expand Down
7 changes: 7 additions & 0 deletions doc/jaas/8x8.vc-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
</script>
<script src="https://8x8.vc/<!--# echo var="subdir" default="" -->config.js" onload="{
config.p2p.disabledCodec='VP9';
config.videoQuality.disabledCodec='VP9';
config.e2ee = { externallyManagedKey: true };
}"/>
<script>
22 changes: 22 additions & 0 deletions doc/jaas/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## How to switch your deployment to [JaaS](https://jaas.8x8.vc) in one easy step

Note: By default it will have e2ee(end-to-end) encryption enabled that works only on chromium based browsers (Chrome, Edge, ...). If a participant joins from another browser or mobile the e2ee is turned off.

In order to use your deployment with JaaS you first need to login to your [JaaS Developer console](https://jaas.8x8.vc/#/apikeys) and generate a key pair.
Use `Add API key` button and then `Generate API key pair`. Make sure you download the generated private key from:

<img src="generated_key_dialog.png" height="250">

Make sure you transfer this downloaded private key to your server. Copy the key id from:

<img src="api_keys_kid.png" height="200">

Now on your server run the helper script passing the private key file and the key id:

```
sudo /usr/share/jitsi-meet/scripts/move-to-jaas.sh /my/path/test-key.pk <key_id>
```

More information about JaaS Api keys at: https://developer.8x8.com/jaas/docs/jaas-console-api-keys

If you want to adjust the enabled services you can do that in /etc/jits/meet/jaas/nginx-jaas.conf. The part after `proxy_set_body` is the jwt token content that will be used for the client tokens. More info about the JaaS tokens: https://developer.8x8.com/jaas/docs/api-keys-jwt
Binary file added doc/jaas/api_keys_kid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/jaas/generated_key_dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions doc/jaas/index-jaas.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<script src='external_api.js' async></script>
<style>html, body, #jaas-container { height: 100%; }</style>
<script type="text/javascript">
function getRoomName(pathname) {
const contextRootEndIndex = pathname.lastIndexOf('/');

return pathname.substring(contextRootEndIndex + 1);
}
window.onload = () => {
const jaasJwt = <!--#include virtual="/jaas-jwt" -->;
const api = new JitsiMeetExternalAPI(
window.location.host, {
roomName: `${jaasJwt.tenant}/${getRoomName(window.location.pathname)}`,
parentNode: document.querySelector('#jaas-container'),
jwt: jaasJwt.token,
e2eeKey: jaasJwt.e2eeKey
});
api.addListener('videoConferenceJoined', () => {
if (jaasJwt.e2eeKey) {
console.info('Toggling e2ee on!')
api.executeCommand('toggleE2EE', true);
}
});
}
</script>
</head>
<body>
<div id="jaas-container" />
</body>
</html>
59 changes: 59 additions & 0 deletions doc/jaas/move-to-jaas.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

set -e

PRIVATE_KEY=$1
JAAS_KEY_ID=$2

if [ ! -f "${PRIVATE_KEY}" ] ; then
echo "You need to specify a correct path for the private key as a first argument."
exit 1;
fi

if [[ ! "${JAAS_KEY_ID}" =~ ^vpaas-magic-cookie-[0-9a-z]+/[0-9a-z]+$ ]]; then
echo "Invalid key id passed as a second argument."
exit 2;
fi

command -v node >/dev/null 2>&1 || { echo >&2 "You must install node first, go to https://nodejs.org. Aborting."; exit 4; }

NODE_VER=$(node -v);
NODE_MAJOR_VER=$(echo ${NODE_VER:1} | cut -d. -f1);

if [ "$NODE_MAJOR_VER" -lt "18" ]; then
echo "Please install latest LTS version of node (18+)";
exit 3;
fi

# we need this util for debconf-set-selections
sudo apt install debconf-utils

# Let's pre-set some settings for token-generator
cat << EOF | sudo debconf-set-selections
token-generator token-generator/private-key string ${PRIVATE_KEY}
token-generator token-generator/kid string ${JAAS_KEY_ID}
EOF

apt install token-generator

mkdir -p /etc/jitsi/meet/jaas

VPASS_COOKIE=$(echo -n ${JAAS_KEY_ID}| cut -d/ -f1)
cp /usr/share/jitsi-meet-web-config/nginx-jaas.conf /etc/jitsi/meet/jaas
sed -i "s/jaas_magic_cookie/${VPASS_COOKIE}/g" /etc/jitsi/meet/jaas/nginx-jaas.conf

cp /usr/share/jitsi-meet-web-config/8x8.vc-config.js /etc/jitsi/meet/jaas/
echo "set \$config_js_location /etc/jitsi/meet/jaas/8x8.vc-config.js;" >> /etc/jitsi/meet/jaas/jaas-vars
echo "set \$custom_index index-jaas.html;" >> /etc/jitsi/meet/jaas/jaas-vars

ln -s /usr/share/jitsi-meet-web-config/index-jaas.html /usr/share/jitsi-meet/index-jaas.html

# let's create the daily key now
/usr/share/jitsi-meet/scripts/update-asap-daily.sh

# let's add to cron daily the update of the asap key
if [ -d /etc/cron.daily ]; then
ln -s /usr/share/jitsi-meet/scripts/update-asap-daily.sh /etc/cron.daily/update-jaas-asap.sh
else
echo "No /etc/cron.daily. Please add to your cron jobs to execute as root daily the script: /usr/share/jitsi-meet/scripts/update-asap-daily.sh"
fi
23 changes: 23 additions & 0 deletions doc/jaas/nginx-jaas.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
include /etc/jitsi/meet/jaas/jaas-vars;
location = /jaas-jwt {
include /etc/jitsi/token-generator/daily-key;
ssi on;
proxy_method POST;
proxy_set_header content-type "application/json";
proxy_set_header Accept-Encoding "";
proxy_set_header Authorization "Bearer $jaas_asap_key";
proxy_pass_request_body off;
proxy_set_body '{"sub":"jaas_magic_cookie","context":{"features":{"livestreaming":false,"outbound-call":false,"sip-outbound-call":false,"transcription":false,"recording":false},"user":{"moderator":true}},"room": "$roomname"}';
proxy_pass http://127.0.0.1:8017/generate/client?e2eeKey=true;
}

location @magic_root_path {
rewrite ^/(.*)$ /index.html break;
}

# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
location ~ ^/jaas_magic_cookie/(.*)$ {
set $subdomain "jaas_magic_cookie.";
set $subdir "jaas_magic_cookie/";
try_files $1 @magic_root_path;
}
9 changes: 9 additions & 0 deletions doc/jaas/update-asap-daily.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
JWT_KID=$(cat /etc/jitsi/token-generator/config | grep SYSTEM_ASAP_BASE_URL_MAPPINGS | cut -d= -f2- | jq -r .[].kid)
JWT_DATE=$(echo -n $JWT_KID | cut -d/ -f2-)
JWT_DATE=${JWT_DATE#jwt-}
KEY_FILE=/etc/jitsi/token-generator/daily-key
echo -n "set \$jaas_asap_key " > ${KEY_FILE}
ASAP_KEY=$(ASAP_SIGNING_KEY_FILE=/etc/jitsi/token-generator/asap-${JWT_DATE}.key ASAP_JWT_KID="${JWT_KID}" ASAP_EXPIRES_IN="1 day" node /usr/share/token-generator/jwt.js| tail -n1)
echo -n "${ASAP_KEY};" >> ${KEY_FILE}

service nginx reload
18 changes: 16 additions & 2 deletions modules/API/external/external_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const commands = {
cancelPrivateChat: 'cancel-private-chat',
closeBreakoutRoom: 'close-breakout-room',
displayName: 'display-name',
e2eeKey: 'e2ee-key',
endConference: 'end-conference',
email: 'email',
grantModerator: 'grant-moderator',
Expand Down Expand Up @@ -561,7 +560,22 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
switch (name) {
case 'video-conference-joined': {
if (typeof this._tmpE2EEKey !== 'undefined') {
this.executeCommand(commands.e2eeKey, this._tmpE2EEKey);

const hexToBytes = hex => {
const bytes = [];

for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substring(c, c + 2), 16));
}

return bytes;
};

this.executeCommand('setMediaEncryptionKey', JSON.stringify({
exportedKey: hexToBytes(this._tmpE2EEKey),
index: 0
}));

this._tmpE2EEKey = undefined;
}

Expand Down

0 comments on commit d8c7f8d

Please sign in to comment.