Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4b50680
Remove unnecessary properties
psrpinto Dec 16, 2022
35ea881
Asset paths can be empty
psrpinto Dec 16, 2022
94f9968
Remove unused function
psrpinto Dec 19, 2022
a218000
Hardcode local storage prefix
psrpinto Dec 19, 2022
01f94f7
Rename file and function
psrpinto Dec 19, 2022
5ea5d3d
Set a cookie when user logs out
psrpinto Dec 19, 2022
123a644
Add a build target for logout
psrpinto Dec 19, 2022
97a24f5
Enqueue logout script when user is not logged in
psrpinto Dec 19, 2022
e2cc070
Move logic to logout.ts
psrpinto Dec 19, 2022
fbb48a8
Iterate localStorage
psrpinto Dec 19, 2022
af036b2
Remove extraneous variable
psrpinto Dec 19, 2022
bd8e26c
Remove extraneous check
psrpinto Dec 19, 2022
d127db5
We're only interested in chatrix_sessions
psrpinto Dec 19, 2022
4f293ac
Move error logging to function
psrpinto Dec 19, 2022
756dafd
Log out all sessions
psrpinto Dec 19, 2022
5bc5264
Once all sessions have been logged out, delete all chatrix data from …
psrpinto Dec 19, 2022
d2cae9d
Correctly log out session
psrpinto Dec 19, 2022
bb9f642
Split for loop
psrpinto Dec 19, 2022
029962b
Improve comments
psrpinto Dec 19, 2022
475977e
Extract code to an async function
psrpinto Dec 19, 2022
161894b
Use await to wait for promises to resolve
psrpinto Dec 19, 2022
eda3c26
Delete from IndexedDB
psrpinto Dec 19, 2022
721b278
Also delete hydrogen data
psrpinto Dec 19, 2022
b02c89e
Variable can be const
psrpinto Dec 19, 2022
4ebe354
Only logout if chatrix-logout cookie is set
psrpinto Dec 20, 2022
dd9a6bc
Fix formatting
psrpinto Dec 20, 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: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"files": [
"src/plugin.php",
"src/Sessions/sessions.php",
"src/Sessions/logout.php",
"src/Block/block.php",
"src/Popup/popup.php",
"src/Admin/admin.php",
Expand Down
22 changes: 10 additions & 12 deletions frontend/iframe/platform/Platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,26 @@ import { ServiceWorkerHandler } from "./ServiceWorkerHandler";
import { StorageFactory } from "./StorageFactory";

export class Platform extends BasePlatform {
private settingsStorage: SettingsStorage;
private sessionInfoStorage: SessionInfoStorage;
private storageFactory: StorageFactory;
private _serviceWorkerHandler: ServiceWorkerHandler;

constructor(options) {
const assetPaths = structuredClone(options.assetPaths);

// Unset serviceWorker path so that the base constructor doesn't register the service worker handler.
delete options.assetPaths.serviceWorker;
delete options.assetPaths?.serviceWorker;
super(options);

// Register our own service worker handler.
let serviceWorkerHandler;
if (assetPaths.serviceWorker && "serviceWorker" in navigator) {
this._serviceWorkerHandler = new ServiceWorkerHandler();
this._serviceWorkerHandler.registerAndStart(assetPaths.serviceWorker);
serviceWorkerHandler = new ServiceWorkerHandler();
serviceWorkerHandler.registerAndStart(assetPaths.serviceWorker);
}

this.settingsStorage = new SettingsStorage("chatrix_setting_v1_");
this.sessionInfoStorage = new SessionInfoStorage("chatrix_sessions_v1");
this.storageFactory = new StorageFactory(this._serviceWorkerHandler);
this.history = new History();
super.storageFactory = new StorageFactory(serviceWorkerHandler);
super._serviceWorkerHandler = serviceWorkerHandler;

super.settingsStorage = new SettingsStorage("chatrix_setting_v1_");
super.sessionInfoStorage = new SessionInfoStorage("chatrix_sessions_v1");
super.history = new History();
}

public get history(): History {
Expand Down
63 changes: 63 additions & 0 deletions frontend/logout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
window.addEventListener('DOMContentLoaded', () => {
const logoutCookieName = "chatrix-logout";
const cookies = document.cookie.split(';');
const hasLogoutCookie = cookies.some(item => item.trim().startsWith(`${logoutCookieName}=`));

if (!hasLogoutCookie) {
return;
}

console.log("Logging out all chatrix sessions");
logoutAndDeleteData().catch(error => console.log(error));
});

async function logoutAndDeleteData() {
let sessionsKey = "";
for (const [key,] of Object.entries(localStorage)) {
if (key.startsWith('chatrix_sessions')) {
sessionsKey = key;
break;
}
}

// Logout all sessions.
const sessions = JSON.parse(localStorage.getItem(sessionsKey) ?? "[]");
let logoutPromises: Promise<Response>[] = [];
if (Array.isArray(sessions)) {
sessions.forEach(session => logoutPromises.push(logoutSession(session)));
}

// Wait for all sessions to have been logged out.
await Promise.all(logoutPromises);

// Delete from local storage.
for (const [key,] of Object.entries(localStorage)) {
if (key.startsWith('chatrix') || key.startsWith('hydrogen')) {
localStorage.removeItem(key);
}
}

// Delete from indexedDB.
const databases = await indexedDB.databases();
for (const database of databases) {
const name = database.name ?? "";
if (name.startsWith('chatrix') || name.startsWith("hydrogen")) {
await indexedDB.deleteDatabase(name);
}
}
}

async function logoutSession(session) {
let promise = fetch(session.homeserver + '/_matrix/client/v3/logout', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + session.accessToken,
},
});

promise.catch(error => {
console.log(`Failed to logout chatrix session. deviceId: ${session.deviceId}`, error);
});

return promise;
}
20 changes: 20 additions & 0 deletions frontend/vite-logout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { resolve } from "path";
import { defineConfig } from "vite";

export default defineConfig(() => {
return {
base: "",
root: __dirname,
envDir: __dirname,
build: {
outDir: resolve(__dirname, "../build/"),
lib: {
entry: resolve(__dirname, `./logout.ts`),
formats: ["iife"],
name: "ChatrixLogout",
fileName: "logout"
},
rollupOptions: {}
}
};
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"scripts": {
"start": "vite --config frontend/vite.ts",
"start:block": "wp-scripts start --webpack-src-dir=frontend/block --output-path=build/block && cp ./frontend/block/block.json ./build/block/",
"build": "tsc && yarn run init && vite build --config frontend/vite-app.ts --emptyOutDir && yarn run build:iframe && yarn run build:block",
"build": "tsc && yarn run init && vite build --config frontend/vite-app.ts --emptyOutDir && yarn run build:logout && yarn run build:iframe && yarn run build:block",
"build:logout": "yarn run init && vite build --config frontend/vite-logout.ts",
"build:iframe": "yarn run init && vite build --config frontend/vite.ts --emptyOutDir",
"build:block": "wp-scripts build --webpack-src-dir=frontend/block --output-path=build/block && cp ./frontend/block/block.json ./build/block/",
"init": "mkdir -p build/.tmp",
Expand Down
15 changes: 15 additions & 0 deletions src/Sessions/logout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Automattic\Chatrix\Sessions;

function init_logout() {
// Set a cookie when user logs out.
add_action(
'wp_logout',
function () {
// Expire in 10 minutes.
$expiration = time() + ( 10 * 60 );
setcookie( 'chatrix-logout', 'true', $expiration, COOKIEPATH, COOKIE_DOMAIN );
}
);
}
60 changes: 0 additions & 60 deletions src/Sessions/sessions.php

This file was deleted.

40 changes: 18 additions & 22 deletions src/plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

use function Automattic\Chatrix\Block\register as register_block;
use function Automattic\Chatrix\Popup\register as register_popup;
use function Automattic\Chatrix\Sessions\init as init_frontend_session_management;
use function Automattic\Chatrix\Sessions\init_logout;

const LOCAL_STORAGE_KEY_PREFIX = 'chatrix';
const SCRIPT_HANDLE_CONFIG = 'chatrix-config';
const SCRIPT_HANDLE_APP = 'chatrix-app';
const CONFIG_VARIABLE = 'ChatrixConfig';
const SCRIPT_HANDLE_CONFIG = 'chatrix-config';
const SCRIPT_HANDLE_APP = 'chatrix-app';
const SCRIPT_HANDLE_LOGOUT = 'chatrix-logout';
const CONFIG_VARIABLE = 'ChatrixConfig';

function main() {
init_frontend_session_management( LOCAL_STORAGE_KEY_PREFIX );
init_logout();
register_scripts();
register_block();
register_popup();
Expand All @@ -33,7 +33,7 @@ function () {
wp_enqueue_script( SCRIPT_HANDLE_CONFIG );
wp_add_inline_script( SCRIPT_HANDLE_CONFIG, 'window.' . CONFIG_VARIABLE . " = $json_data;" );

// Note we don't enqueue the script yet. It will be enqueue whenever SCRIPT_HANDLE_APP
// Note we don't enqueue the SCRIPT_HANDLE_APP script yet. It will be enqueued whenever SCRIPT_HANDLE_APP
// is specified as a dependency of another script.
wp_register_script(
SCRIPT_HANDLE_APP,
Expand All @@ -42,25 +42,21 @@ function () {
automattic_chatrix_version(),
true
);

if ( ! is_user_logged_in() ) {
wp_register_script(
SCRIPT_HANDLE_LOGOUT,
root_url() . '/logout.iife.js',
array(),
automattic_chatrix_version(),
false
);
wp_enqueue_script( SCRIPT_HANDLE_LOGOUT );
}
}
);
}

function root_url(): string {
return plugins_url() . '/chatrix/build';
}

function get_local_storage_key( string $instance_id ): string {
$current_user = wp_get_current_user();
$local_storage_key = LOCAL_STORAGE_KEY_PREFIX;

if ( ! empty( $instance_id ) ) {
$local_storage_key .= '_' . $instance_id;
}

if ( 0 !== $current_user->ID ) {
$local_storage_key .= '_' . $current_user->user_login;
}

return $local_storage_key;
}