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

added docs for frontend code #289

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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 kraken_frontend/src/components/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";

/** React props for [`<Textarea />`]{@link Textarea} */
export type TextareaProps = {
/** The textarea's current value */
/** The text area's current value */
value: string;
/** Callback invoked when the user changed the value */
onChange: (newValue: string) => void;
Expand Down
4 changes: 3 additions & 1 deletion kraken_frontend/src/context/user.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { toast } from "react-toastify";
import { Api } from "../api/api";
import { ApiError, StatusCode } from "../api/error";
import { FullUser, UserPermission } from "../api/generated/models";
import { FullUser, UserPermission } from "../api/generated";
import WS from "../api/websocket";
import Loading from "../components/loading";
import CONSOLE from "../utils/console";
Expand Down Expand Up @@ -34,9 +34,11 @@ const USER_CONTEXT = React.createContext<UserContext>({
USER_CONTEXT.displayName = "UserContext";
export default USER_CONTEXT;

/** React props for [`<UserProvider />`]{@link UserProvider} */
type UserProviderProps = {
children?: React.ReactNode;
};
/** React state for [`<UserProvider />`]{@link UserProvider} */
type UserProviderState = {
user: FullUser | "unauthenticated" | "loading";
};
Expand Down
6 changes: 5 additions & 1 deletion kraken_frontend/src/views/admin/users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import Input from "../../components/input";
import Loading from "../../components/loading";
import { check, handleApiError } from "../../utils/helper";

/** View to expose the `/api/v1/admin/users` endpoints */
/**
* View to expose the `/api/v1/admin/users` endpoints
*
* @returns JSX.Element
*/
export default function AdminUsers() {
/** Store a user to ask for confirmation before deleting him */
const [confirmDelete, setConfirmDelete] = React.useState<FullUser | null>(null);
Expand Down
6 changes: 5 additions & 1 deletion kraken_frontend/src/views/admin/workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { SimpleWorkspace } from "../../api/generated";
import Loading from "../../components/loading";
import { handleApiError } from "../../utils/helper";

/** View to expose the `/api/v1/admin/workspaces` endpoints */
/**
* View to expose the `/api/v1/admin/workspaces` endpoints
*
* @returns JSX.Element
*/
export default function AdminWorkspaces() {
const [workspaces, setWorkspaces] = React.useState<Array<SimpleWorkspace> | undefined>(undefined);

Expand Down
27 changes: 27 additions & 0 deletions kraken_frontend/src/views/gobal-popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,37 @@ import WS from "../api/websocket";
import { handleApiError } from "../utils/helper";
import Invitation from "./workspace/invitation/invitation";

/** workspace invitation popup */
type Popup = WsInvitationToWorkspace;

/** type for workspace invitation*/
type WsInvitationToWorkspace = {
/**
* popup type
*/
type: "invitation";
/**
* UUID of invitation
*/
invitationUuid: UUID;
/**
* workspace the invitation is for
*/
workspace: SimpleWorkspace;
/**
* user who sent out workspace invitation
*/
from: SimpleUser;
};

/**
* Handle all global popups (currently only invitations)
* and display them on top of kraken
*
* new popup types can be added here
*
* @returns displayed popup
*/
export default function GlobalPopup() {
const [popups, setPopups] = React.useState<Array<Popup>>([]);

Expand Down Expand Up @@ -46,6 +68,11 @@ export default function GlobalPopup() {
popup = popups[0];
}

/**
* switch trough popup type to select the displayed popup
*
* @returns <Invitation/>
*/
const popupDisplay = () => {
switch (popup.type) {
case "invitation":
Expand Down
5 changes: 5 additions & 0 deletions kraken_frontend/src/views/home.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Future home page of kraken with a relevant overview for current user
*
* @returns JSX.Element
*/
export default function Home() {
return <div></div>;
}
11 changes: 8 additions & 3 deletions kraken_frontend/src/views/knowledge-base.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { ROUTES } from "../routes";
import "../styling/knowledge-base.css";

type KnowledgeBaseProps = {};

export default function KnowledgeBase(props: KnowledgeBaseProps) {
/**
* Page to display knowledge base
*
* currently redirecting to {@link ListFindingDefinition `< ListFindingDefinition />`}
*
* @returns JSX.Element page displaying knowledge base
*/
export default function KnowledgeBase() {
return (
<div className={"knowledge-base-container"}>
<div className={"pane"}>
Expand Down
30 changes: 30 additions & 0 deletions kraken_frontend/src/views/kraken-network.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import PlusIcon from "../svg/plus";
import { handleApiError, sleep } from "../utils/helper";
import { useTriggerUpdate } from "../utils/trigger-hook";

/**
* Page to manually create new leeches and view existing ones
*
* Page only visible for admin users
*
* @returns JSX.Element page to view and create leeches
*/
export default function KrakenNetwork() {
const [leeches, setLeeches] = React.useState<Array<SimpleLeech> | undefined>(undefined);
const [showPopup, setShowPopup] = React.useState<boolean>(false);
Expand All @@ -28,6 +35,9 @@ export default function KrakenNetwork() {
const rightBottom = React.useRef<SVGElement | null | undefined>(null);
const triggerUpdate = useTriggerUpdate();

/**
* Api call to get all existing leeches, then call function to trigger rerender
*/
function retrieveLeeches() {
Api.admin.leeches.all().then(
handleApiError(async ({ leeches }) => {
Expand All @@ -43,6 +53,9 @@ export default function KrakenNetwork() {
}, []);

React.useEffect(() => {
/**
* Trigger rerender when window is resized
*/
const onResize = () => {
triggerUpdate();
};
Expand All @@ -52,6 +65,13 @@ export default function KrakenNetwork() {
return () => window.removeEventListener("resize", onResize);
}, []);

/**
* Api call to create a new leech
*
* On success call {@link retrieveLeeches}
*
* @param e React.FormEvent<HTMLFormElement>
*/
function createLeech(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();

Expand Down Expand Up @@ -317,6 +337,16 @@ export default function KrakenNetwork() {
);
}

/**
* function to create a curved, dashed <path /> between 2 points (P1, P2) in 2D space
*
* @param fromX X value of P1
* @param fromY Y value of P1
* @param toX X value of P2
* @param toY Y value of P2
*
* @returns <path/>
*/
function curve(fromX: number, fromY: number, toX: number, toY: number) {
const stepX = (toX - fromX) / 3;
return (
Expand Down
7 changes: 7 additions & 0 deletions kraken_frontend/src/views/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ import "../styling/login.css";
import LoginLogoIcon from "../svg/login_logo";
import { handleApiError } from "../utils/helper";

/** React props for [`<Login />`]{@link Login} */
type LoginProps = {
onLogin(): void;
};

/**
* Page for users to login
*/
export default function Login(props: LoginProps) {
const { onLogin } = props;
const [username, setUsername] = React.useState<string>("");
const [password, setPassword] = React.useState<string>("");

/**
* Api call to authenticate and login the user
*/
function performLogin() {
Api.auth.login(username, password).then(
handleApiError(() => {
Expand Down
26 changes: 26 additions & 0 deletions kraken_frontend/src/views/me.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import CloseIcon from "../svg/close";
import CopyIcon from "../svg/copy";
import { check, handleApiError } from "../utils/helper";

/**
* Page displaying User Settings.
* User can manage account settings and API keys
*
* @returns JSX.Element page for user settings
*/
export default function Me() {
const context = React.useContext(USER_CONTEXT);

Expand All @@ -29,6 +35,9 @@ export default function Me() {
const [apiKeys, setApiKeys] = React.useState<Array<FullApiKey>>([]);
const [user, setUser] = React.useState<FullUser>(context.user);

/**
* Api call to get all existing api keys
*/
async function retrieveApiKeys() {
await Api.user.apiKeys.all().then(
handleApiError((keys) => {
Expand All @@ -37,6 +46,10 @@ export default function Me() {
);
}

/**
* Api call to create a new api key.
* Call {@link retrieveApiKeys} on success
*/
async function createApiKey() {
if (apiKeyName === "") {
toast.error("Name must not be empty");
Expand All @@ -58,6 +71,12 @@ export default function Me() {
setDisplayName(context.user.displayName);
}, []);

/**
* Api call to delete an api key.
* Call {@link retrieveApiKeys} on success
*
* @param uuid of Api key to be deleted
*/
async function deleteApiKey(uuid: UUID) {
Api.user.apiKeys.delete(uuid).then(
handleApiError(async (_) => {
Expand All @@ -67,6 +86,9 @@ export default function Me() {
);
}

/**
* Api call to update user's username and/or displayname
*/
async function updateAccount() {
if (username.length === 0) {
toast.error("Username must not be empty");
Expand Down Expand Up @@ -96,6 +118,10 @@ export default function Me() {
);
}

/**
* Api call to change user's password.
* Reload users information on success.
*/
function changePwd() {
if (
!check([
Expand Down
10 changes: 10 additions & 0 deletions kraken_frontend/src/views/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import UsersIcon from "../svg/users";
import WorkspaceIcon from "../svg/workspace";
import "./running-attacks";

/**
* Type for all menu options of kraken
*/
type MenuItem =
| "me"
| "workspaces"
Expand All @@ -21,6 +24,13 @@ type MenuItem =
| "knowledge"
| "settings";

/**
* Tall vertical pane with icons for all the menu options
*
* Click on an icon to visit the related page via {@link ROUTES}
*
* @returns JSX.Element vertical menu bar
*/
function Menu() {
const context = React.useContext(USER_CONTEXT);
const [active, setActive] = React.useState<MenuItem>("workspaces");
Expand Down
1 change: 1 addition & 0 deletions kraken_frontend/src/views/oauth-request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Checkbox from "../components/checkbox";
import "../styling/oauth-request.css";
import { handleApiError } from "../utils/helper";

/** React props for {@link OauthRequest `<OauthRequest />`} */
type OAuthRequestProps = {
uuid: UUID;
};
Expand Down
29 changes: 29 additions & 0 deletions kraken_frontend/src/views/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import CloseIcon from "../svg/close";
import CopyIcon from "../svg/copy";
import { copyToClipboard, handleApiError } from "../utils/helper";

/**
* Page showing the kraken settings
*
* Only visible for admin user
*
* @returns JSX.Element
*/
export default function Settings() {
const [settings, setSettings] = React.useState<SettingsFull | null>(null);
const [oauthApplications, setOauthApplications] = React.useState<Array<FullOauthClient>>([]);
Expand All @@ -19,10 +26,16 @@ export default function Settings() {
const [wordlistPath, setWordlistPath] = React.useState<string>("");
const [wordlistDescription, setWordlistDescription] = React.useState<string>("");

/**
* Api call to get the currently active settings
*/
async function retrieveSettings() {
await Api.admin.settings.get().then(handleApiError((settings) => setSettings(settings)));
}

/**
* Api call to get the current existing OAuth apps
*/
async function getOAuthApps() {
await Api.admin.oauthApplications.all().then(
handleApiError((apps) => {
Expand All @@ -31,6 +44,9 @@ export default function Settings() {
);
}

/**
* Api call to get all wordlists including their paths
*/
async function updateWordlists() {
await Api.admin.wordlists.all().then(
handleApiError((wordlists) => {
Expand All @@ -43,6 +59,11 @@ export default function Settings() {
Promise.all([getOAuthApps(), retrieveSettings(), updateWordlists()]).then();
}, []);

/**
* Api call to create a new wordlist
*
* Name and path are required
*/
async function createWordlist() {
if (wordlistName === "") {
toast.error("Name of the wordlist must not be empty");
Expand All @@ -62,6 +83,9 @@ export default function Settings() {
.then(handleApiError((_) => toast.success("Created wordlist")));
}

/**
* Api call to save the updated settings
*/
async function saveSettings() {
if (settings === null) {
return;
Expand All @@ -70,6 +94,11 @@ export default function Settings() {
await Api.admin.settings.update(settings).then(handleApiError((_) => toast.success("Settings updated")));
}

/**
* Api call to create a new application
*
* Name and uri are required
*/
async function createOAuthApp() {
if (newOAuthAppName === "" || newOAuthAppRedirectUrl === "") {
toast.error("App name and redirect uri must not be empty");
Expand Down
Loading
Loading