forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
+ create user, login, logout
This commit is contained in:
86
src/app.ts
86
src/app.ts
@@ -1,18 +1,22 @@
|
||||
import { getUserId } from "./identity";
|
||||
import {
|
||||
User,
|
||||
addOption,
|
||||
toggleVote,
|
||||
setDeadline,
|
||||
clearDeadline,
|
||||
getDeadline,
|
||||
} from "./state";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { initSync } from "./sync";
|
||||
import { initUserSync } from "./userSync";
|
||||
import { StatusBar } from "./components/StatusBar";
|
||||
import { PollTitle } from "./components/PollTitle";
|
||||
import { AddOption } from "./components/AddOption";
|
||||
import { PollList } from "./components/PollList";
|
||||
import { ShareSection } from "./components/ShareSection";
|
||||
import { DeadlineTimer } from "./components/DeadlineTimer";
|
||||
import { generateUserKeyPair, exportPrivateKey, savePrivateKeyToFile, exportPublicKey, stringToCryptoKey } from "./crypto";
|
||||
|
||||
const ROOM_PARAM = "room";
|
||||
|
||||
@@ -38,8 +42,9 @@ function ensureRoomId(): string {
|
||||
|
||||
export function initApp(container: HTMLElement): () => void {
|
||||
const roomId = ensureRoomId();
|
||||
const userId = getUserId();
|
||||
const sync = initSync(roomId);
|
||||
const userSync = initUserSync();
|
||||
let user : User | undefined = undefined;
|
||||
|
||||
const shareUrl = window.location.href;
|
||||
|
||||
@@ -47,12 +52,12 @@ export function initApp(container: HTMLElement): () => void {
|
||||
|
||||
const actions = {
|
||||
addOption: (label: string) => {
|
||||
if (isVotingClosed()) return;
|
||||
return addOption(sync.options, label, userId);
|
||||
if (!user || isVotingClosed()) return;
|
||||
return addOption(sync.options, label, user.userid);
|
||||
},
|
||||
toggleVote: (optionId: string) => {
|
||||
if (isVotingClosed()) return;
|
||||
toggleVote(sync.votes, userId, optionId);
|
||||
if (!user || isVotingClosed()) return;
|
||||
toggleVote(sync.votes, user.userid, optionId);
|
||||
},
|
||||
startDeadline: (durationMs: number) => {
|
||||
setDeadline(sync.deadlineMap, durationMs);
|
||||
@@ -60,6 +65,73 @@ export function initApp(container: HTMLElement): () => void {
|
||||
clearDeadline: () => {
|
||||
clearDeadline(sync.deadlineMap);
|
||||
},
|
||||
onLoginLogout: async (event: Event) => {
|
||||
if(user){
|
||||
user = undefined
|
||||
return false;
|
||||
} else {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const file = target.files?.[0];
|
||||
|
||||
if (file) {
|
||||
try {
|
||||
const content = await file.text();
|
||||
console.log("File loaded: ");
|
||||
if (file.name && content) {
|
||||
try {
|
||||
const uuid = file.name.replace(".pem", "");
|
||||
// Standardize the string for the importer
|
||||
const pkBase64 = content.replace(/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----/g, "").replace(/\s+/g, "");
|
||||
|
||||
const key = await stringToCryptoKey(pkBase64, "private");
|
||||
|
||||
user = {
|
||||
userid: uuid,
|
||||
private_key: key,
|
||||
public_key: undefined, // Note: You might need to import a pub key too!
|
||||
};
|
||||
|
||||
console.log("Login successful for:", uuid);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Crypto Import Error:", err);
|
||||
alert("The file content is not a valid Private Key.");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to read file", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onCreateUser: async (event: Event) => {
|
||||
try {
|
||||
const keypair = await generateUserKeyPair();
|
||||
|
||||
console.log('keypair:', keypair);
|
||||
const uuid = uuidv4();
|
||||
user = {
|
||||
userid: uuid,
|
||||
private_key: keypair.privateKey,
|
||||
public_key: keypair.publicKey,
|
||||
};
|
||||
|
||||
const prvKeyString = await exportPrivateKey(keypair.privateKey);
|
||||
|
||||
savePrivateKeyToFile(prvKeyString,uuid+".pem")
|
||||
|
||||
|
||||
const pubKeyString = await exportPublicKey(keypair.publicKey);
|
||||
|
||||
userSync.users.set(user.userid,pubKeyString)
|
||||
return true;
|
||||
} catch (err) {
|
||||
user = undefined
|
||||
console.error("Failed to create new User!", err);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function isVotingClosed() {
|
||||
@@ -85,7 +157,7 @@ export function initApp(container: HTMLElement): () => void {
|
||||
<span>Polly</span>
|
||||
`;
|
||||
|
||||
const statusBar = StatusBar(sync.provider);
|
||||
const statusBar = StatusBar(sync.provider,userSync.provider,actions.onLoginLogout,actions.onCreateUser);
|
||||
header.append(wordmark, statusBar);
|
||||
|
||||
// Main card
|
||||
@@ -98,7 +170,7 @@ export function initApp(container: HTMLElement): () => void {
|
||||
if (result && !result.ok) return result.error;
|
||||
return null;
|
||||
});
|
||||
const pollList = PollList(sync.options, sync.votes, userId, isVotingClosed, actions.toggleVote);
|
||||
const pollList = PollList(sync.options, sync.votes, user, isVotingClosed, actions.toggleVote);
|
||||
const deadlineTimer = DeadlineTimer(
|
||||
sync.deadlineMap,
|
||||
actions.startDeadline,
|
||||
|
||||
Reference in New Issue
Block a user