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

Revoke viewer session #1045

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ services:
restart: "on-failure"

admin-portal:
image: boxyhq/jackson:1.11.0
image: boxyhq/jackson:1.13.0
ports:
- "5225:5225"
networks:
Expand Down
1 change: 1 addition & 0 deletions integration/test/viewer/createsavedexport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ describe("Viewer API", function () {
const desc = {
environmentId: Env.EnvironmentID,
groupId: groupID,
id: token,
};
const tkn = jwt.sign(desc, process.env.HMAC_SECRET_VIEWER);
chai
Expand Down
31 changes: 31 additions & 0 deletions src/handlers/revokeViewerSessions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Authenticator from "../security/Authenticator";
import modelDeleteViewerDescriptors from "../models/viewer_descriptor/delete";
import { RawResponse } from "../router";

export default async function handlerRaw(req): Promise<RawResponse> {
const auth = req.get("Authorization");
const projectId = req.params.projectId;
const groupId = req.params.groupId;
const actorId = req.params.actorId;
await revokeViewerSessions(auth, projectId, actorId, groupId);
return {
status: 200,
body: "",
};
}

export async function revokeViewerSessions(
auth: string,
projectId: string,
actorId: string,
groupId: string
): Promise<void> {
const apiToken = await Authenticator.default().getApiTokenOr401(auth, projectId);

await modelDeleteViewerDescriptors({
projectId,
environmentId: apiToken.environmentId,
groupId,
actorId,
});
}
22 changes: 22 additions & 0 deletions src/models/viewer_descriptor/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import getPgPool from "../../persistence/pg";

const pgPool = getPgPool();

export interface Options {
projectId: string;
environmentId: string;
groupId: string;
actorId: string;
}

export default async function modelDeleteViewerDescriptors(opts: Options): Promise<void> {
const q = `
DELETE FROM viewer_descriptors
WHERE project_id = $1 AND
environment_id = $2 AND
group_id = $3 AND
actor_id = $4`;
const values = [opts.projectId, opts.environmentId, opts.groupId, opts.actorId];

await pgPool.query(q, values);
}
6 changes: 6 additions & 0 deletions src/routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// core
import createViewerSession from "./handlers/createViewerSession";
import getInvite from "./handlers/getInvite";
import revokeViewerSessions from "./handlers/revokeViewerSessions";
import graphQL from "./handlers/graphql";

// admin
Expand Down Expand Up @@ -179,6 +180,11 @@ export default {
method: "post",
handler: createViewerSession,
},
revokeViewerSessions: {
path: "/viewer/v1/project/:projectId/group/:groupId/actor/:actorId/viewersessions",
method: "delete",
handler: revokeViewerSessions,
},
viewerCreateEitapiToken: {
path: "/viewer/v1/project/:projectId/eitapi_token",
method: "post",
Expand Down
17 changes: 14 additions & 3 deletions src/security/vouchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import jwt from "jsonwebtoken";
import config from "../config";

import ViewerDescriptor from "../models/viewer_descriptor/def";
import getViewerToken from "../models/viewer_descriptor/get";

export interface AdminClaims {
userId: string;
Expand Down Expand Up @@ -31,13 +32,23 @@ export async function validateAdminVoucher(voucher: string): Promise<AdminClaims
}

export async function validateViewerDescriptorVoucher(voucher: string): Promise<ViewerDescriptor> {
return new Promise<ViewerDescriptor>((resolve, reject) => {
jwt.verify(voucher, config.HMAC_SECRET_VIEWER, (err, claims) => {
const claims = await new Promise<ViewerDescriptor>((resolve, reject) => {
jwt.verify(voucher, config.HMAC_SECRET_VIEWER, (err, claimsObj) => {
if (err) {
reject(err);
return;
}
resolve(claims);
resolve(claimsObj);
});
});

const token = await getViewerToken({
id: claims.id,
});

if (!token) {
throw new Error("Invalid token");
}

return claims;
}
Loading