mirror of
https://github.com/morten-olsen/parcel.git
synced 2026-02-08 01:36:24 +01:00
init
This commit is contained in:
146
src/contexts/Encryption.tsx
Normal file
146
src/contexts/Encryption.tsx
Normal file
@@ -0,0 +1,146 @@
|
||||
import React, { useState, useCallback, useContext, createContext } from 'react';
|
||||
import * as openpgp from 'openpgp';
|
||||
import { nanoid } from 'nanoid';
|
||||
import GithubContext from './Github';
|
||||
|
||||
export interface FileType {
|
||||
name: string;
|
||||
reciever: string;
|
||||
status: 'encrypting' | 'failed' | 'encrypted';
|
||||
error?: any;
|
||||
link?: string;
|
||||
}
|
||||
|
||||
interface EncryptionContextType {
|
||||
files: {[id: string]: FileType};
|
||||
addFile: (file: File) => Promise<void>;
|
||||
addText: (text: string) => Promise<void>;
|
||||
deleteFile: (id: string) => void;
|
||||
}
|
||||
|
||||
const EncryptionContext = createContext<EncryptionContextType>({
|
||||
files: {},
|
||||
addFile: async () => { throw new Error('Not using provider'); },
|
||||
addText: async () => { throw new Error('Not using provider'); },
|
||||
deleteFile: async () => { throw new Error('Not using provider'); },
|
||||
});
|
||||
|
||||
const encrypt = async (keys: string[], content: string) => {
|
||||
const armoredKeys = await Promise.all(keys.map(openpgp.key.readArmored));
|
||||
console.log(armoredKeys);
|
||||
const message = openpgp.message.fromText(content);
|
||||
const encrypted = await openpgp.encrypt({
|
||||
message,
|
||||
armor: true,
|
||||
publicKeys: armoredKeys.reduce((output, key: any) => [...output, ...key.keys], []),
|
||||
});
|
||||
const { data } = encrypted;
|
||||
const blob = new Blob([data], {
|
||||
type: 'text/text',
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
return url;
|
||||
};
|
||||
|
||||
const EncryptionProvider: React.FC = ({
|
||||
children,
|
||||
}) => {
|
||||
const { username, keys } = useContext(GithubContext);
|
||||
const [files, setFiles] = useState<EncryptionContextType['files']>({});
|
||||
|
||||
const deleteFile = useCallback((id: string) => {
|
||||
delete files[id];
|
||||
setFiles({
|
||||
...files,
|
||||
});
|
||||
}, [files]);
|
||||
|
||||
const add = (name: string = nanoid()) => {
|
||||
const file: FileType = {
|
||||
name: `${name}.asc`,
|
||||
reciever: username,
|
||||
status: 'encrypting',
|
||||
};
|
||||
setFiles(files => ({
|
||||
...files,
|
||||
[name]: file,
|
||||
}));
|
||||
|
||||
const setError = (err: any) => {
|
||||
console.error(err);
|
||||
setFiles(files => ({
|
||||
...files,
|
||||
[name]: {
|
||||
...files[name],
|
||||
status: 'failed',
|
||||
error: err,
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
const setContent = (text: string, keys: string[]) => {
|
||||
const run = async () => {
|
||||
try {
|
||||
const encrypted = await encrypt(keys, text);
|
||||
setFiles(files => ({
|
||||
...files,
|
||||
[name]: {
|
||||
...files[name],
|
||||
link: encrypted,
|
||||
status: 'encrypted'
|
||||
},
|
||||
}));
|
||||
} catch (err) {
|
||||
setError(err);
|
||||
}
|
||||
};
|
||||
run();
|
||||
};
|
||||
|
||||
return {
|
||||
setContent,
|
||||
setError,
|
||||
};
|
||||
}
|
||||
|
||||
const addFile = useCallback(async (file: File) => {
|
||||
console.log('a', keys, file);
|
||||
if (!keys) return;
|
||||
const addedFile = add(file.name);
|
||||
const reader = new FileReader()
|
||||
|
||||
reader.onabort = addedFile.setError,
|
||||
reader.onerror = addedFile.setError,
|
||||
reader.onload = () => {
|
||||
console.log('foo', file);
|
||||
addedFile.setContent(reader.result as string, keys);
|
||||
}
|
||||
reader.readAsText(file)
|
||||
}, [keys, username]);
|
||||
|
||||
const addText = useCallback(async (text: string) => {
|
||||
if (!keys) return;
|
||||
const file = add();
|
||||
file.setContent(text, keys);
|
||||
}, [keys, username]);
|
||||
|
||||
return (
|
||||
<EncryptionContext.Provider
|
||||
value={{
|
||||
files,
|
||||
addFile,
|
||||
addText,
|
||||
deleteFile,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</EncryptionContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export {
|
||||
EncryptionProvider,
|
||||
};
|
||||
|
||||
export default EncryptionContext;
|
||||
|
||||
68
src/contexts/Github.tsx
Normal file
68
src/contexts/Github.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import React, { useState, useEffect, createContext } from 'react';
|
||||
|
||||
interface GithubContextType {
|
||||
username: string;
|
||||
user?: any;
|
||||
keys?: string[];
|
||||
error?: any;
|
||||
state: 'loading' | 'ready' | 'failed'
|
||||
}
|
||||
|
||||
interface Props {
|
||||
username: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const GithubContext = createContext<GithubContextType>({
|
||||
username: 'unknown',
|
||||
state: 'failed',
|
||||
});
|
||||
|
||||
const GithubProvider: React.FC<Props> = ({
|
||||
username,
|
||||
children,
|
||||
}) => {
|
||||
const [keys, setKeys] = useState<GithubContextType['keys'] | undefined>();
|
||||
const [state, setState] = useState<GithubContextType['state']>('loading');
|
||||
const [error, setError] = useState<GithubContextType['state'] | undefined>();
|
||||
const [user, setUser] = useState<GithubContextType['user'] | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
const run = async () => {
|
||||
try {
|
||||
const keysRes = await fetch(`https://api.github.com/users/${username}/gpg_keys`);
|
||||
const userRes = await fetch(`https://api.github.com/users/${username}`);
|
||||
const keys = await keysRes.json();
|
||||
const user = await userRes.json();
|
||||
setState('ready');
|
||||
setKeys(keys.map((key: any) => key.raw_key));
|
||||
setUser(user);
|
||||
} catch (err) {
|
||||
setState('failed');
|
||||
setError(err);
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
}, [username]);
|
||||
|
||||
return (
|
||||
<GithubContext.Provider
|
||||
value={{
|
||||
username,
|
||||
user,
|
||||
keys,
|
||||
state,
|
||||
error,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</GithubContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export {
|
||||
GithubProvider,
|
||||
};
|
||||
|
||||
export default GithubContext;
|
||||
Reference in New Issue
Block a user