add waffle library, handle file upload, authenticate user with oauth and see if they have the link's email associated to their account
This commit is contained in:
@@ -14,15 +14,17 @@ import "../css/app.css"
|
||||
// import {Socket} from "phoenix"
|
||||
// import socket from "./socket"
|
||||
//
|
||||
import "phoenix_html"
|
||||
import {Socket} from "phoenix"
|
||||
import topbar from "topbar"
|
||||
import {LiveSocket} from "phoenix_live_view"
|
||||
import "phoenix_html";
|
||||
import {Socket} from "phoenix";
|
||||
import topbar from "topbar";
|
||||
import {LiveSocket} from "phoenix_live_view";
|
||||
|
||||
import SplashPage from './pages/SplashPage';
|
||||
import JustPage from './pages/JustPage'
|
||||
import ForPage from './pages/ForPage'
|
||||
import YouPage from './pages/YouPage'
|
||||
import JustPage from './pages/JustPage';
|
||||
import ForPage from './pages/ForPage';
|
||||
import YouPage from './pages/YouPage';
|
||||
import AuthPage from './pages/AuthPage';
|
||||
import RevealPage from './pages/RevealPage';
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
|
||||
@@ -42,5 +44,5 @@ liveSocket.connect()
|
||||
window.liveSocket = liveSocket
|
||||
|
||||
window.Components = {
|
||||
SplashPage, JustPage, ForPage, YouPage
|
||||
SplashPage, JustPage, ForPage, YouPage, AuthPage, RevealPage
|
||||
}
|
||||
|
@@ -1,16 +1,54 @@
|
||||
// import HexMix from "../utils/hexmix";
|
||||
// const fragmentData = window.location.hash.split('.');
|
||||
// if (fragmentData.length <= 0) {
|
||||
// alert("No key found in fragment URI");
|
||||
// return;
|
||||
// }
|
||||
// const key = HexMix.hexToUint8(fragmentData[0]);
|
||||
// const iv = HexMix.hexToUint8(fragmentData[1]);
|
||||
import { Button, CenteredContainer, GlobalStyle, Header2, Header3, Input, Label, Spacer, TextAlignWrapper } from "@intended/intended-ui";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
// const importedKey = await window.crypto.subtle.importKey(
|
||||
// 'raw',
|
||||
// key,
|
||||
// 'AES-GCM',
|
||||
// true,
|
||||
// ['encrypt', 'decrypt']
|
||||
// );
|
||||
type AuthPageProps = {
|
||||
csrf: string,
|
||||
service: string,
|
||||
recipient: string
|
||||
}
|
||||
|
||||
const AuthPage = (props: AuthPageProps) => {
|
||||
const { service, recipient } = props;
|
||||
// const [recipientInput, setRecipientInput] = useState("");
|
||||
// const [serviceSelect, setServiceSelect] = useState("github");
|
||||
|
||||
// useEffect(() => {
|
||||
|
||||
// }, [])
|
||||
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<GlobalStyle />
|
||||
<CenteredContainer fullscreen>
|
||||
<CenteredContainer>
|
||||
<Header2 style={{ margin: ".4rem" }}>Someone sent you a secret</Header2>
|
||||
<Header3 small>
|
||||
Please verify your identity to reveal this message.
|
||||
</Header3>
|
||||
<Spacer space="3rem" />
|
||||
<TextAlignWrapper align="left">
|
||||
<Label htmlFor="usernameEmail">Username / Email</Label>
|
||||
</TextAlignWrapper>
|
||||
<Input
|
||||
variant="disabled-medium"
|
||||
id="usernameEmail"
|
||||
value={recipient}
|
||||
/>
|
||||
<Spacer space="3rem" />
|
||||
<TextAlignWrapper align="left">
|
||||
<Label htmlFor="service">Service</Label>
|
||||
</TextAlignWrapper>
|
||||
<Input variant="disabled-medium" id="service" value={service} />
|
||||
<Spacer space="3rem" />
|
||||
<a href={`https://intended.link/auth/${service}`}>
|
||||
<Button variant="primary" wide onClick={() => {}}>
|
||||
Verify
|
||||
</Button>
|
||||
</a>
|
||||
</CenteredContainer>
|
||||
</CenteredContainer>
|
||||
</React.StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
export default AuthPage;
|
||||
|
@@ -3,9 +3,13 @@ import React, { useState } from "react";
|
||||
import { ProgressIndicator, Header2, Button, IconArrow, Label, Input, Select, CenteredContainer, SpaceBetweenContainer, Spacer, TextAlignWrapper, GlobalStyle } from "@intended/intended-ui";
|
||||
|
||||
|
||||
const ForPage = () => {
|
||||
type ForPageProps = {
|
||||
csrf: string
|
||||
}
|
||||
|
||||
const ForPage = (props: ForPageProps) => {
|
||||
const [recipientInput, setRecipientInput] = useState("");
|
||||
const [serviceSelect, setServiceSelect] = useState("");
|
||||
const [serviceSelect, setServiceSelect] = useState("github");
|
||||
|
||||
const handleRecipientInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement>
|
||||
@@ -18,14 +22,14 @@ const ForPage = () => {
|
||||
};
|
||||
|
||||
const postContacts = async () => {
|
||||
const fragmentData = window.location.hash.split('.');
|
||||
if (fragmentData.length <= 0) {
|
||||
alert("No key found in fragment URI");
|
||||
return;
|
||||
}
|
||||
// const fragmentData = window.location.hash.split('.');
|
||||
// if (fragmentData.length <= 0) {
|
||||
// alert("No key found in fragment URI");
|
||||
// return;
|
||||
// }
|
||||
|
||||
const linkId = sessionStorage.getItem("link_id");
|
||||
if (linkId == null || linkId == "") {
|
||||
if (!linkId) {
|
||||
alert("No created link found in storage");
|
||||
return;
|
||||
}
|
||||
@@ -36,10 +40,18 @@ const ForPage = () => {
|
||||
formData.append("link_id", linkId);
|
||||
|
||||
try {
|
||||
await fetch(`${window.location.origin}/just/for`, {
|
||||
const results = await fetch(`${window.location.origin}/just/for`, {
|
||||
headers: {
|
||||
"X-CSRF-Token": props.csrf
|
||||
},
|
||||
body: formData,
|
||||
method: "POST"
|
||||
});
|
||||
if (!results.ok) {
|
||||
throw new Error('Network response was not OK');
|
||||
}
|
||||
|
||||
await results.json();
|
||||
window.location.href = `${window.location.origin}/just/for/you`;
|
||||
} catch (err: any) {
|
||||
alert(err.message);
|
||||
@@ -74,7 +86,9 @@ const ForPage = () => {
|
||||
id="serviceSelector"
|
||||
onChange={handleServiceChange}
|
||||
value={serviceSelect}
|
||||
/>
|
||||
>
|
||||
<option value='github'>Github</option>
|
||||
</Select>
|
||||
<Spacer space="3rem" />
|
||||
<SpaceBetweenContainer>
|
||||
<Button variant="secondary" onClick={() => window.location.href = "/just"}>
|
||||
|
@@ -1,13 +1,21 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { ProgressIndicator, Header2, Button, IconArrow, Label, FileInput, TextArea, CenteredContainer, Spacer, TextAlignWrapper, GlobalStyle } from '@intended/intended-ui';
|
||||
import HexMix from "../utils/hexmix";
|
||||
|
||||
const JustPage = (props) => {
|
||||
type JustPageProps = {
|
||||
csrf: string
|
||||
}
|
||||
|
||||
const JustPage = (props: JustPageProps) => {
|
||||
const [secretInput, setSecretInput] = useState("");
|
||||
const [fileInput, setFileInput] = useState<File | null>(null);
|
||||
const [fileName, setFileName] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
sessionStorage.clear();
|
||||
}, [])
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setSecretInput(e.target.value);
|
||||
};
|
||||
@@ -51,18 +59,20 @@ const JustPage = (props) => {
|
||||
const blobData = new Blob([encrypted]);
|
||||
|
||||
formData.append('text_content', blobData);
|
||||
formData.append('filetype', 'text/plain');
|
||||
formData.append('filename', 'secret.txt');
|
||||
// formData.append('filetype', 'text/plain');
|
||||
// formData.append('filename', 'secret.txt');
|
||||
|
||||
try {
|
||||
const link: unknown = await fetch(`${window.location.origin}/just`, {
|
||||
const link: Response = await fetch(`${window.location.origin}/just`, {
|
||||
headers: {
|
||||
"X-CSRF-Token": props.csrf
|
||||
},
|
||||
body: formData,
|
||||
method: "POST"
|
||||
});
|
||||
sessionStorage.setItem("link_id", (link as Link).id);
|
||||
const { id: link_id } = await link.json()
|
||||
|
||||
sessionStorage.setItem("link_id", link_id);
|
||||
sessionStorage.setItem("key_hex", keyHex);
|
||||
sessionStorage.setItem("iv_hex", ivHex);
|
||||
window.location.href = `${window.location.origin}/just/for`;
|
||||
|
61
assets/js/pages/RevealPage.tsx
Normal file
61
assets/js/pages/RevealPage.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Button, CenteredContainer, GlobalStyle, Header2, Header3, InputButtonWithIcon, Label, SpaceBetweenContainer, Spacer, TextAlignWrapper, TextAreaParagraph } from "@intended/intended-ui";
|
||||
import React, { useEffect, useState } from "react";
|
||||
// import HexMix from "../utils/hexmix";
|
||||
// const fragmentData = window.location.hash.split('.');
|
||||
// if (fragmentData.length <= 0) {
|
||||
// alert("No key found in fragment URI");
|
||||
// return;
|
||||
// }
|
||||
// const key = HexMix.hexToUint8(fragmentData[0]);
|
||||
// const iv = HexMix.hexToUint8(fragmentData[1]);
|
||||
|
||||
// const importedKey = await window.crypto.subtle.importKey(
|
||||
// 'raw',
|
||||
// key,
|
||||
// 'AES-GCM',
|
||||
// true,
|
||||
// ['encrypt', 'decrypt']
|
||||
// );
|
||||
|
||||
|
||||
const RevealPage = () => {
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<GlobalStyle />
|
||||
<CenteredContainer fullscreen>
|
||||
<CenteredContainer>
|
||||
<Header2 style={{ margin: ".4rem" }}>Someone sent you a secret</Header2>
|
||||
<Header3 small>
|
||||
Please verify your identity to reveal this message.
|
||||
</Header3>
|
||||
<Spacer space="3rem" />
|
||||
|
||||
<SpaceBetweenContainer>
|
||||
<Label htmlFor="secretMessage">Secret message</Label>
|
||||
<Label htmlFor="secretMessage">Sent 8/24/21 @ 1:27pm</Label>
|
||||
</SpaceBetweenContainer>
|
||||
<TextAreaParagraph id="secretMessage">
|
||||
"Sup. What are you doing for lunch?"
|
||||
</TextAreaParagraph>
|
||||
|
||||
<Spacer space="3rem" />
|
||||
<TextAlignWrapper align="left">
|
||||
<Label htmlFor="service">Secret File</Label>
|
||||
</TextAlignWrapper>
|
||||
<InputButtonWithIcon
|
||||
variant="download"
|
||||
id="downloadfile"
|
||||
value="1780983.jpg"
|
||||
onClick={() => {}}
|
||||
/>
|
||||
<Spacer space="3rem" />
|
||||
<Button variant="secondary" wide onClick={() => {}}>
|
||||
Send a secret
|
||||
</Button>
|
||||
</CenteredContainer>
|
||||
</CenteredContainer>
|
||||
</React.StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
export default RevealPage;
|
@@ -8,11 +8,10 @@ const YouPage = () => {
|
||||
const keyHex = sessionStorage.getItem("key_hex");
|
||||
const ivHex = sessionStorage.getItem("iv_hex");
|
||||
|
||||
`${window.location.origin}/just/for/you/${linkId}#${keyHex}.${ivHex}`
|
||||
return "";
|
||||
return `${window.location.origin}/just/for/you/${linkId}#${keyHex}.${ivHex}`;
|
||||
};
|
||||
|
||||
const [url, setUrl] = useState(calculateUrl());
|
||||
const [url, _setUrl] = useState(calculateUrl());
|
||||
|
||||
const copyUrl = async () => {
|
||||
try {
|
||||
@@ -51,7 +50,7 @@ const YouPage = () => {
|
||||
<Input
|
||||
variant="disabled-light"
|
||||
id="encodedSecret"
|
||||
value="\4RÏÇmÄyÆFÕ¬Ð$CÑÓÃyÛ"
|
||||
value={url}
|
||||
/>
|
||||
<Spacer space="3rem" />
|
||||
<SpaceBetweenContainer>
|
||||
|
Reference in New Issue
Block a user