temp commit

This commit is contained in:
Rohan Sircar 2020-07-07 22:11:14 +05:30
parent e06d98752a
commit 140721b542
44 changed files with 23277 additions and 252 deletions

View File

@ -55,6 +55,7 @@
} }
}, },
"scripts": { "scripts": {
"watch": "watchify src/main/frontend/chat/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o src/main/resources/static/js/bundle.js" "watch": "watchify src/main/frontend/chat/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o src/main/resources/static/js/bundle.js",
"watch-admin": "watchify src/main/frontend/admin/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o src/main/resources/static/js/adminBundle.js"
} }
} }

View File

@ -0,0 +1,10 @@
import { changePassphrase } from "./pages/user/ChangePassphrase";
import { EncryptionServiceFactory } from "../common/service/EncryptionServiceFactory";
import log from "loglevel";
log.setLevel("TRACE");
const es = EncryptionServiceFactory.getEncryptionService();
$("#changePassphraseForm").on("submit", (event) => {
event.preventDefault();
changePassphrase(es);
});

View File

@ -0,0 +1,96 @@
import { EncryptionService } from "../../../common/service/EncryptionService";
import { Routes } from "../../../common/routes/Routes";
import { ChatMessageDTO } from "../../../common/dto/ChatMessageDTO";
import {
ReencryptionDTO,
DecryptedDTO,
} from "../../../common/dto/ReencryptionDTO";
import { Credentials } from "../../../common/global/Credentials";
import { MessageCipher } from "../../../common/entity/MessageCipher";
import log from "loglevel";
export async function changePassphrase(es: EncryptionService) {
// $("#changePassphraseForm").val();
const user =
(document.getElementById("changePassphraseDropDown") as HTMLOptionElement)
.value || "error";
const passphraseOld: string = $("#passphraseOld").val() as string;
const passphraseNew: string = $("#passphraseNew").val() as string;
log.debug(Credentials.authToken);
const messages = await getAllMessages(user, Credentials.authToken);
const decrypted = Promise.all(
messages.map(
async (m): Promise<DecryptedDTO> => {
const msg = await es.decryptAsPromise(passphraseOld, m.messageCipher);
const m2 = { ...m, messageId: m.messageCipher.id, message: msg };
return m2;
}
)
);
const reencrypted = (await decrypted).map((m) => {
const mdto = es.encrypt(passphraseNew, m.message);
const mc = <MessageCipher>{ id: m.messageId, ...mdto };
const rdto = <ReencryptionDTO>{ ...m, messageCipher: mc };
return rdto;
});
log.debug(reencrypted);
const decryptedAgain = Promise.all(
reencrypted.map(async (m) => {
return es.decryptAsPromise(passphraseNew, m.messageCipher);
})
);
const deb = await decryptedAgain;
log.debug(deb);
sendReencryptedMessages(reencrypted, Credentials.authToken);
}
async function getAllMessages(user: string, authToken: string) {
let headers = new Headers();
// headers.append('Accept','application/json')
// headers.append('Content-Type', 'application/json');
headers.append("X-AUTH-TOKEN", authToken);
let response = await fetch(`${Routes.Admin.getAllMessagesURL}${user}`, {
method: "GET",
headers: headers,
});
return response.json() as Promise<ReencryptionDTO[]>;
}
async function getAllRegularUsers(authToken: string) {
let headers = new Headers();
// headers.append('Accept','application/json')
// headers.append('Content-Type', 'application/json');
headers.append("X-AUTH-TOKEN", authToken);
let response = await fetch(`${Routes.Admin.getAllRegularUsersURL}`, {
method: "GET",
headers: headers,
});
let data = (await response.json()) as string[];
return data;
}
function sendReencryptedMessages(
rrencryptionDTOs: ReencryptionDTO[],
authToken: string
) {
let headers = new Headers();
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
// headers.append('Accept','application/json')
headers.append("Content-Type", "application/json");
headers.append("X-AUTH-TOKEN", authToken);
fetch(Routes.Admin.reencryptURL, {
method: "POST",
headers: headers,
body: JSON.stringify(rrencryptionDTOs),
}).then((response) => console.log(response));
}

View File

@ -1,4 +1,4 @@
import { Model } from "../../common/model/AbstractModel"; import { Model } from "../model/AbstractModel";
import { View } from "../view/AbstractView"; import { View } from "../view/AbstractView";
// simple restrictions that MVC impose: The Control has a reference to the View and Model + the View has a reference to the Model and the Controller.It also does not have any Observer implementation in the Model, so that the View can update based on it. // simple restrictions that MVC impose: The Control has a reference to the View and Model + the View has a reference to the Model and the Controller.It also does not have any Observer implementation in the Model, so that the View can update based on it.

View File

@ -1,12 +1,12 @@
import { Controller } from "./AbstractController"; import { Controller } from "./AbstractController";
import "../../common/model/AbstractModel" import "../model/AbstractModel"
import "../../common/model/UserModel" import "../model/UserModel"
import "../view/AbstractView" import "../view/AbstractView"
import "../view/UserView" import "../view/UserView"
import { Model } from "../../common/model/AbstractModel"; import { Model } from "../model/AbstractModel";
import { View } from "../view/AbstractView"; import { View } from "../view/AbstractView";
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { ChatModel } from "../../common/model/ChatModel"; import { ChatModel } from "../model/ChatModel";
import { ChatView } from "../view/ChatView"; import { ChatView } from "../view/ChatView";
export class ChatController { export class ChatController {

View File

@ -1,13 +1,13 @@
import { Controller } from "./AbstractController"; import { Controller } from "./AbstractController";
import "../../common/model/AbstractModel" import "../model/AbstractModel"
import "../../common/model/UserModel" import "../model/UserModel"
import "../view/AbstractView" import "../view/AbstractView"
import "../view/UserView" import "../view/UserView"
import { Model } from "../../common/model/AbstractModel"; import { Model } from "../model/AbstractModel";
import { View } from "../view/AbstractView"; import { View } from "../view/AbstractView";
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
import { UserView } from "../view/UserView"; import { UserView } from "../view/UserView";
import { UserModel } from "../../common/model/UserModel"; import { UserModel } from "../model/UserModel";
export class UserController { export class UserController {
private _model: UserModel; private _model: UserModel;

View File

@ -3,15 +3,15 @@ import * as Handlebars from "handlebars";
import * as log from "loglevel"; import * as log from "loglevel";
import { ChatController } from "./controller/ChatController"; import { ChatController } from "./controller/ChatController";
import { UserController } from "./controller/UserController"; import { UserController } from "./controller/UserController";
import { ChatModel } from "../common/model/ChatModel"; import { ChatModel } from "./model/ChatModel";
import { ChatModelHelper } from "../common/model/ChatModelHelper"; import { ChatModelHelper } from "./model/ChatModelHelper";
import { UserModel } from "../common/model/UserModel"; import { UserModel } from "./model/UserModel";
import { AlertifyNotificationService } from "./service/AlertifyNotificationService"; import { AlertifyNotificationService } from "../common/service/AlertifyNotificationService";
import { EncryptionServiceFactory } from "./service/EncryptionServiceFactory"; import { EncryptionServiceFactory } from "../common/service/EncryptionServiceFactory";
import { FuseSearchService } from "./service/FuseSearchService"; import { FuseSearchService } from "../common/service/FuseSearchService";
import { MarkDownItMarkDownService } from "./service/MarkDownItMarkDownService"; import { MarkDownItMarkDownService } from "../common/service/MarkDownItMarkDownService";
import { NotificationService } from "./service/NotificationService"; import { NotificationService } from "../common/service/NotificationService";
import { SearchService } from "./service/SearchService"; import { SearchService } from "../common/service/SearchService";
import { TemplateFactory } from "./template/TemplateFactory"; import { TemplateFactory } from "./template/TemplateFactory";
import { ChatView } from "./view/ChatView"; import { ChatView } from "./view/ChatView";
import { ChatViewDeps } from "./view/ChatViewDeps"; import { ChatViewDeps } from "./view/ChatViewDeps";

View File

@ -0,0 +1,7 @@
import { Subject } from "../observe/Observable";
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
export interface Model extends Subject<any> {
someBusinessMethod(data: Object): void;
}

View File

@ -1,11 +1,11 @@
import { Subject } from "../../chat/observe/Observable"; import { Subject } from "../observe/Observable";
import { Observer } from "../../chat/observe/Observer"; import { Observer } from "../observe/Observer";
import { JsonAPI } from "../../chat/singleton/JsonAPI"; import { JsonAPI } from "../singleton/JsonAPI";
import { ChatMessageViewModel } from "../../chat/viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { ChatModelHelper } from "./ChatModelHelper"; import { ChatModelHelper } from "./ChatModelHelper";
import log = require("loglevel"); import log = require("loglevel");
import { ObserverData } from "../../chat/observe/ObserverData"; import { ObserverData } from "../observe/ObserverData";
import { ActiveUserViewModel } from "../../chat/viewmodel/ActiveUserViewModel"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
import moment = require("moment"); import moment = require("moment");
interface Params { interface Params {

View File

@ -1,10 +1,10 @@
import * as log from "loglevel"; import * as log from "loglevel";
import { ChatMessageDTO } from "../../chat/dto/ChatMessageDTO"; import { ChatMessageDTO } from "../../common/dto/ChatMessageDTO";
import { EncryptionService } from "../service/EncryptionService"; import { EncryptionService } from "../../common/service/EncryptionService";
import { NotificationService } from "../../chat/service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { JsonAPI } from "../../chat/singleton/JsonAPI"; import { JsonAPI } from "../singleton/JsonAPI";
import { Sprintf } from "../../chat/singleton/Sprintf"; import { Sprintf } from "../../common/global/Sprintf";
import { ChatMessageViewModel } from "../../chat/viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { fetchErrorHandler } from "./FetchErrorHandler"; import { fetchErrorHandler } from "./FetchErrorHandler";
export class ChatModelHelper { export class ChatModelHelper {
@ -145,7 +145,12 @@ export class ChatModelHelper {
return; return;
} }
headers.append("X-AUTH-TOKEN", JsonAPI.authToken); headers.append("X-AUTH-TOKEN", JsonAPI.authToken);
const url = Sprintf(JsonAPI.CHAT_MESSAGE_PAGE_GET, toUser, page, JsonAPI.CHAT_PAGE_SIZE); const url = Sprintf(
JsonAPI.CHAT_MESSAGE_PAGE_GET,
toUser,
page,
JsonAPI.CHAT_PAGE_SIZE
);
log.debug(url); log.debug(url);
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", method: "GET",

View File

@ -1,6 +1,6 @@
import log = require("loglevel"); import log = require("loglevel");
import { NotificationService } from "../../chat/service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { Sprintf } from "../../chat/singleton/Sprintf"; import { Sprintf } from "../../common/global/Sprintf";
// import { sprintf } from "sprintf-js"; // import { sprintf } from "sprintf-js";
///<reference path="../SprintfTest.d.ts" /> ///<reference path="../SprintfTest.d.ts" />

View File

@ -1,10 +1,10 @@
import * as log from "loglevel"; import * as log from "loglevel";
import { Subject } from "../../chat/observe/Observable"; import { Subject } from "../observe/Observable";
import { Observer } from "../../chat/observe/Observer"; import { Observer } from "../observe/Observer";
import { JsonAPI } from "../../chat/singleton/JsonAPI"; import { JsonAPI } from "../singleton/JsonAPI";
import { ActiveUserViewModel } from "../../chat/viewmodel/ActiveUserViewModel"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
import { fetchErrorHandler } from "./FetchErrorHandler"; import { fetchErrorHandler } from "./FetchErrorHandler";
import { NotificationService } from "../../chat/service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
export class UserModel implements Subject<ActiveUserViewModel> { export class UserModel implements Subject<ActiveUserViewModel> {
/** /**

View File

@ -1,5 +1,5 @@
// simple restrictions that MVC impose: The Control has a reference to the View and Model + the View has a reference to the Model and the Controller.It also does not have any Observer implementation in the Model, so that the View can update based on it. // simple restrictions that MVC impose: The Control has a reference to the View and Model + the View has a reference to the Model and the Controller.It also does not have any Observer implementation in the Model, so that the View can update based on it.
import { Model } from "../../common/model/AbstractModel"; import { Model } from "../model/AbstractModel";
import { Controller } from "../controller/AbstractController"; import { Controller } from "../controller/AbstractController";
import { Observer } from "../observe/Observer"; import { Observer } from "../observe/Observer";
export interface View extends Observer<any> { export interface View extends Observer<any> {

View File

@ -1,18 +1,18 @@
import * as DOMPurify from "dompurify"; import * as DOMPurify from "dompurify";
import * as log from "loglevel"; import * as log from "loglevel";
import { ChatMessageDTO } from "../dto/ChatMessageDTO"; import { ChatMessageDTO } from "../../common/dto/ChatMessageDTO";
import { MessageCipherDTO } from "../dto/MessageCipherDTO"; import { MessageCipherDTO } from "../../common/dto/MessageCipherDTO";
import { ChatModel } from "../../common/model/ChatModel"; import { ChatModel } from "../model/ChatModel";
import { Observer } from "../observe/Observer"; import { Observer } from "../observe/Observer";
import { EncryptionService } from "../../common/service/EncryptionService"; import { EncryptionService } from "../../common/service/EncryptionService";
import { MarkDownService } from "../service/MarkDownService"; import { MarkDownService } from "../../common/service/MarkDownService";
import { JsonAPI } from "../singleton/JsonAPI"; import { JsonAPI } from "../singleton/JsonAPI";
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { ChatViewDeps } from "./ChatViewDeps"; import { ChatViewDeps } from "./ChatViewDeps";
import { fetchHandler } from "./FetchHandler"; import { fetchHandler } from "./FetchHandler";
import { ObserverData } from "../observe/ObserverData"; import { ObserverData } from "../observe/ObserverData";
import { NotificationService } from "../service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { UserModel } from "../../common/model/UserModel"; import { UserModel } from "../model/UserModel";
export class ChatView implements Observer<ChatMessageViewModel> { export class ChatView implements Observer<ChatMessageViewModel> {
private readonly _chatModel: ChatModel; private readonly _chatModel: ChatModel;

View File

@ -1,9 +1,9 @@
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { ChatModel } from "../../common/model/ChatModel"; import { ChatModel } from "../model/ChatModel";
import { MarkDownService } from "../service/MarkDownService"; import { MarkDownService } from "../../common/service/MarkDownService";
import { EncryptionService } from "../../common/service/EncryptionService"; import { EncryptionService } from "../../common/service/EncryptionService";
import { NotificationService } from "../service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { UserModel } from "../../common/model/UserModel"; import { UserModel } from "../model/UserModel";
export interface ChatViewDeps { export interface ChatViewDeps {
chatModel: ChatModel; chatModel: ChatModel;

View File

@ -1,33 +1,52 @@
import { NotificationService } from "../service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { Sprintf } from "../singleton/Sprintf"; import { Sprintf } from "../../common/global/Sprintf";
export function fetchHandler(response: Response, ns: NotificationService) { export function fetchHandler(response: Response, ns: NotificationService) {
if (response.ok) { if (response.ok) {
return response.json().then((json: any) => { return response
.json()
.then((json: any) => {
// the status was ok and there is a json body // the status was ok and there is a json body
// return Promise.resolve({ json: json, response: response }); // return Promise.resolve({ json: json, response: response });
ns.success('Message sent succesfully' + Sprintf(" (http code %d)", response.status)); ns.success(
}).catch((err: any) => { "Message sent succesfully" +
Sprintf(" (http code %d)", response.status)
);
})
.catch((err: any) => {
// the status was ok but there is no json body // the status was ok but there is no json body
// return Promise.resolve({ response: response }); // return Promise.resolve({ response: response });
ns.success('Message sent succesfully' + Sprintf(" (http code %d)", response.status)); ns.success(
"Message sent succesfully" +
Sprintf(" (http code %d)", response.status)
);
}); });
} else { } else {
return response.json().catch((err: any) => { return response
.json()
.catch((err: any) => {
// the status was not ok and there is no json body // the status was not ok and there is no json body
// throw new Error(response.statusText); // throw new Error(response.statusText);
ns.error('Some error occured. Please try again.'); ns.error("Some error occured. Please try again.");
}).then((json: any) => { })
.then((json: any) => {
// the status was not ok but there is a json body // the status was not ok but there is a json body
// throw new Error(json.error.message); // example error message returned by a REST // throw new Error(json.error.message); // example error message returned by a REST
// let delay = alertify.get('notifier', 'delay'); // let delay = alertify.get('notifier', 'delay');
// alertify.set('notifier', 'delay', 30); // alertify.set('notifier', 'delay', 30);
let errorMessage = ""; let errorMessage = "";
json.errors.forEach(function(data: any) { json.errors.forEach(function (data: any) {
errorMessage += Sprintf("Field Name: %s \n Rejected value: %s \n Reason: %s \n", data.field_name, data.rejected_value, data.error_message); errorMessage += Sprintf(
"Field Name: %s \n Rejected value: %s \n Reason: %s \n",
data.field_name,
data.rejected_value,
data.error_message
);
}); });
ns.errorWithDelay(Sprintf('There were errors in your message - %s', errorMessage), 30); ns.errorWithDelay(
Sprintf("There were errors in your message - %s", errorMessage),
30
);
// alertify.set('notifier', 'delay', delay); // alertify.set('notifier', 'delay', delay);
}); });
} }

View File

@ -1,14 +1,14 @@
import { Observer } from "../observe/Observer"; import { Observer } from "../observe/Observer";
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
import { ChatModel } from "../../common/model/ChatModel"; import { ChatModel } from "../model/ChatModel";
import log = require("loglevel"); import log = require("loglevel");
import * as DOMPurify from "dompurify"; import * as DOMPurify from "dompurify";
import { SearchService } from "../service/SearchService"; import { SearchService } from "../../common/service/SearchService";
import { UserModel } from "../../common/model/UserModel"; import { UserModel } from "../model/UserModel";
import { UserViewDeps } from "./UserViewDeps"; import { UserViewDeps } from "./UserViewDeps";
import { ObserverData } from "../observe/ObserverData"; import { ObserverData } from "../observe/ObserverData";
import { JsonAPI } from "../singleton/JsonAPI"; import { JsonAPI } from "../singleton/JsonAPI";
import { NotificationService } from "../service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
export class UserView implements Observer<ActiveUserViewModel> { export class UserView implements Observer<ActiveUserViewModel> {

View File

@ -1,11 +1,11 @@
import { UserModel } from "../../common/model/UserModel"; import { UserModel } from "../model/UserModel";
import { ChatModel } from "../../common/model/ChatModel"; import { ChatModel } from "../model/ChatModel";
import { SearchService } from "../service/SearchService"; import { SearchService } from "../../common/service/SearchService";
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
import { NotificationService } from "../service/NotificationService"; import { NotificationService } from "../../common/service/NotificationService";
export interface UserViewDeps { export interface UserViewDeps {
model: UserModel; model: UserModel;

View File

@ -0,0 +1,16 @@
import { MessageCipher } from "../entity/MessageCipher";
export interface ReencryptionDTO {
toUser: string;
fromUser: string;
messageCipher: MessageCipher;
messageTime: Date;
}
export interface DecryptedDTO {
toUser: string;
fromUser: string;
messageId: number;
message: string;
messageTime: Date;
}

View File

@ -0,0 +1,5 @@
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
export interface MessageCipher extends MessageCipherDTO {
id: number;
}

View File

@ -0,0 +1,4 @@
export namespace Credentials {
export const principleName: string = localStorage.getItem("username") || "";
export const authToken: string = localStorage.getItem("authToken") || "";
}

View File

@ -1,7 +0,0 @@
import { Subject } from "../../chat/observe/Observable";
import { ActiveUserViewModel } from "../../chat/viewmodel/ActiveUserViewModel";
export interface Model extends Subject<any> {
someBusinessMethod(data: Object): void;
}

View File

@ -0,0 +1,5 @@
export namespace Admin {
export const getAllMessagesURL = `/api/admin/get/messages/`; //hostAddress set in thymeleaf backend
export const reencryptURL = `/api/admin/post/re-encrypt`;
export const getAllRegularUsersURL = `/api/admin/get/users`;
}

View File

View File

@ -0,0 +1,5 @@
import { Admin as _admin } from "./Admin";
export namespace Routes {
export const Admin = _admin;
}

View File

@ -1,7 +1,10 @@
import { MessageCipherDTO } from "../../chat/dto/MessageCipherDTO"; import { MessageCipherDTO } from "../dto/MessageCipherDTO";
export interface EncryptionService { export interface EncryptionService {
encrypt(passphrase: string, plainText: string): any; encrypt(passphrase: string, plainText: string): MessageCipherDTO;
decrypt(passphrase: string, cipher: MessageCipherDTO): string; decrypt(passphrase: string, cipher: MessageCipherDTO): string;
decryptAsPromise(passphrase: string, cipher: MessageCipherDTO): Promise<string> decryptAsPromise(
passphrase: string,
cipher: MessageCipherDTO
): Promise<string>;
} }

View File

@ -1,5 +1,5 @@
import { EncryptionService } from "../../common/service/EncryptionService"; import { EncryptionService } from "./EncryptionService";
import { SJCLEncryptionService } from "../../common/service/SJCLEncryptionService"; import { SJCLEncryptionService } from "./SJCLEncryptionService";
// import PromiseWorker = require('promise-worker'); // import PromiseWorker = require('promise-worker');
import PromiseWorker from "promise-worker"; import PromiseWorker from "promise-worker";

View File

@ -1,32 +1,41 @@
import { EncryptionService } from "./EncryptionService"; import { EncryptionService } from "./EncryptionService";
import * as sjcl from "sjcl"; import * as sjcl from "sjcl";
import { MessageCipherDTO } from "../../chat/dto/MessageCipherDTO"; import { MessageCipherDTO } from "../dto/MessageCipherDTO";
import PromiseWorker from "promise-worker"; import PromiseWorker from "promise-worker";
export class SJCLEncryptionService implements EncryptionService { export class SJCLEncryptionService implements EncryptionService {
private _params: sjcl.SjclCipherParams = { mode: "gcm", ts: 128, adata: "", iter: 10000 }; private _params: sjcl.SjclCipherParams = {
mode: "gcm",
ts: 128,
adata: "",
iter: 10000,
};
private readonly _promiseWorker: PromiseWorker; private readonly _promiseWorker: PromiseWorker;
constructor(promiseWorker: PromiseWorker) { constructor(promiseWorker: PromiseWorker) {
this._promiseWorker = promiseWorker; this._promiseWorker = promiseWorker;
} }
public encrypt(passphrase: string, plainText: string): MessageCipherDTO { public encrypt(passphrase: string, plainText: string): MessageCipherDTO {
const fn = () => { const fn = () => {
// @ts-ignore // @ts-ignore
const cipher = sjcl.encrypt(passphrase, plainText, this._params) const cipher = sjcl.encrypt(passphrase, plainText, this._params);
return cipher as unknown as string return (cipher as unknown) as string;
} };
return JSON.parse(fn()) return JSON.parse(fn());
} }
public decrypt(passphrase: string, cipher: MessageCipherDTO): string { public decrypt(passphrase: string, cipher: MessageCipherDTO): string {
return sjcl.decrypt(passphrase, JSON.stringify(cipher)); return sjcl.decrypt(passphrase, JSON.stringify(cipher));
} }
public async decryptAsPromise(passphrase: string, cipher: MessageCipherDTO): Promise<string> { public async decryptAsPromise(
const decrypted = await this._promiseWorker.postMessage({ "passphrase": passphrase, "cipher": cipher }) passphrase: string,
cipher: MessageCipherDTO
): Promise<string> {
const decrypted = await this._promiseWorker.postMessage<
string,
{ passphrase: string; cipher: MessageCipherDTO }
>({ passphrase: passphrase, cipher: cipher });
return decrypted; return decrypted;
} }
} }

View File

@ -1,6 +1,6 @@
import registerPromiseWorker from 'promise-worker/register'; import registerPromiseWorker from 'promise-worker/register';
import * as sjcl from 'sjcl' import * as sjcl from 'sjcl'
import { MessageCipherDTO } from '../../chat/dto/MessageCipherDTO'; import { MessageCipherDTO } from '../../common/dto/MessageCipherDTO';
registerPromiseWorker((payload: { passphrase: string, cipher: MessageCipherDTO }) => { registerPromiseWorker((payload: { passphrase: string, cipher: MessageCipherDTO }) => {

View File

@ -51,11 +51,16 @@ public class AdminRESTController {
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}") @GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName, public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName,
@PathVariable Instant lastMessageTime, Principal principal) { @PathVariable Instant lastMessageTime, Principal principal) {
List<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages( List<ChatMessageDTO> chatMessageDTOs = chatService
principal.getName(), userName, lastMessageTime); .getNewMessages(principal.getName(), userName, lastMessageTime);
return chatMessageDTOs; return chatMessageDTOs;
} }
@GetMapping("/regular-users")
public List<String> getAllRegularUsers() {
return userService.getAllRegularUsers();
}
@GetMapping("/get/users") @GetMapping("/get/users")
public List<String> getAllOtherUsers(Principal principal) { public List<String> getAllOtherUsers(Principal principal) {
return userService.findAllOtherUsers(principal.getName()); return userService.findAllOtherUsers(principal.getName());

View File

@ -1,6 +1,6 @@
package org.ros.chatto.dto; package org.ros.chatto.dto;
import java.util.Date; import java.time.Instant;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
@ -14,10 +14,10 @@ import lombok.Data;
public class ReencryptionDTO { public class ReencryptionDTO {
@NotBlank(message = "Username should not be blank") @NotBlank(message = "Username should not be blank")
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "Username must be alphanumeric") @Pattern(regexp = "^[A-Za-z0-9]+$", message = "Username must be alphanumeric")
@Size(max=15) @Size(max = 15)
private String toUser, fromUser; private String toUser, fromUser;
@NotBlank @NotBlank
@Size(max=600) @Size(max = 600)
private MessageCipher messageCipher; private MessageCipher messageCipher;
private Date messageTime; private Instant messageTime;
} }

View File

@ -1,19 +1,19 @@
console.log('Hello world!'); console.log("Hello world!");
var getAllMessagesURL = `http://${hostAddress}/api/admin/get/messages/`; //hostAddress set in thymeleaf backend var getAllMessagesURL = `http://${hostAddress}/api/admin/get/messages/`; //hostAddress set in thymeleaf backend
var reencryptURL = `http://${hostAddress}/api/admin/post/re-encrypt`; var reencryptURL = `http://${hostAddress}/api/admin/post/re-encrypt`;
var getAllRegularUsersURL = `http://${hostAddress}/api/regular-users`; var getAllRegularUsersURL = `http://${hostAddress}/api/regular-users`;
var username = sessionStorage.getItem('username'); var username = sessionStorage.getItem("username");
var password = sessionStorage.getItem('password'); var password = sessionStorage.getItem("password");
var authToken = 'Basic ' + btoa(username + ":" + password); var authToken = "Basic " + btoa(username + ":" + password);
var iterations = 10000; var iterations = 10000;
function handleAddToAdminForm() { function handleAddToAdminForm() {
document.getElementById('addUserToAdminForm').addEventListener( document
'submit', .getElementById("addUserToAdminForm")
function(e) { .addEventListener("submit", function (e) {
e.preventDefault(); e.preventDefault();
getAllRegularUsers() getAllRegularUsers();
// .then(usernamesArray => { // .then(usernamesArray => {
// console.lo // console.lo
// }); // });
@ -21,32 +21,41 @@ function handleAddToAdminForm() {
} }
function handleChangePassphraseForm() { function handleChangePassphraseForm() {
document.getElementById('changePassphraseForm').addEventListener( document
'submit', .getElementById("changePassphraseForm")
function(e) { .addEventListener("submit", function (e) {
e.preventDefault(); e.preventDefault();
let changePassphraseDropDown = document.getElementById('changePassphraseDropDown'); let changePassphraseDropDown = document.getElementById(
"changePassphraseDropDown"
);
let user = changePassphraseDropDown.value; let user = changePassphraseDropDown.value;
let passphraseOld = document.getElementById('passphraseOld'); let passphraseOld = document.getElementById("passphraseOld");
let passphraseNew = document.getElementById('passphraseNew'); let passphraseNew = document.getElementById("passphraseNew");
// let messageCipherNew = {}; // let messageCipherNew = {};
console.log(user); console.log(user);
getAllMessages(user) getAllMessages(user)
.then(json => { .then((json) => {
console.log(json); console.log(json);
return json; return json;
}) })
.then(json => { .then((json) => {
let jsonNew = []; let jsonNew = [];
let messageCiphers = []; let messageCiphers = [];
let chatMessageDTOs = []; let chatMessageDTOs = [];
if (json.length > 0) { if (json.length > 0) {
json.forEach(function(obj) { json.forEach(function (obj) {
let newObj = obj; let newObj = obj;
let messageID = obj.messageCipher.id; let messageID = obj.messageCipher.id;
let plainText = sjcl.decrypt(passphraseOld.value, JSON.stringify(obj.messageCipher)); let plainText = sjcl.decrypt(
let messageCipherNew = sjcl.encrypt(passphraseNew.value, plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations }); passphraseOld.value,
JSON.stringify(obj.messageCipher)
);
let messageCipherNew = sjcl.encrypt(
passphraseNew.value,
plainText,
{ mode: "gcm", ts: 128, adata: "", iter: iterations }
);
// let plainText = sjcl.decrypt("password", JSON.stringify(obj.messageCipher)); // let plainText = sjcl.decrypt("password", JSON.stringify(obj.messageCipher));
// let messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations }); // let messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
// console.log(messageCipherNew) // console.log(messageCipherNew)
@ -63,28 +72,29 @@ function handleChangePassphraseForm() {
// let messageCipherJson = JSON.stringify(messageCipherNewObj); // let messageCipherJson = JSON.stringify(messageCipherNewObj);
let chatMessageDTO = { let chatMessageDTO = {
"toUser": user, toUser: user,
"fromUser": username, fromUser: username,
"messageCipher": messageCipherNewObj messageCipher: messageCipherNewObj,
} };
chatMessageDTOs.push(chatMessageDTO); chatMessageDTOs.push(chatMessageDTO);
}); });
// console.log(jsonNew); // console.log(jsonNew);
} }
// sendReencryptedMessages(JSON.stringify(jsonNew)); // sendReencryptedMessages(JSON.stringify(jsonNew));
console.log console.log;
sendReencryptedMessages(JSON.stringify(chatMessageDTOs)); sendReencryptedMessages(JSON.stringify(chatMessageDTOs));
// sendReencryptedMessages(JSON.stringify(messageCiphers)); // sendReencryptedMessages(JSON.stringify(messageCiphers));
return jsonNew; return jsonNew;
}) })
.then(json => { .then((json) => {
json.forEach(function(obj) { json.forEach(function (obj) {
let plainText = sjcl.decrypt("password2", JSON.stringify(obj.messageCipher)); let plainText = sjcl.decrypt(
"password2",
JSON.stringify(obj.messageCipher)
);
console.log(plainText); console.log(plainText);
}) });
}); });
}); });
} }
@ -93,10 +103,10 @@ async function getAllMessages(user) {
let headers = new Headers(); let headers = new Headers();
// headers.append('Accept','application/json') // headers.append('Accept','application/json')
// headers.append('Content-Type', 'application/json'); // headers.append('Content-Type', 'application/json');
headers.append('Authorization', authToken); headers.append("Authorization", authToken);
let response = await fetch(`${getAllMessagesURL}${user}`, { let response = await fetch(`${getAllMessagesURL}${user}`, {
method: 'GET', method: "GET",
headers: headers headers: headers,
}); });
let data = await response.json(); let data = await response.json();
return data; return data;
@ -106,10 +116,10 @@ async function getAllRegularUsers() {
let headers = new Headers(); let headers = new Headers();
// headers.append('Accept','application/json') // headers.append('Accept','application/json')
// headers.append('Content-Type', 'application/json'); // headers.append('Content-Type', 'application/json');
headers.append('Authorization', authToken); headers.append("Authorization", authToken);
let response = await fetch(`${getAllRegularUsersURL}`, { let response = await fetch(`${getAllRegularUsersURL}`, {
method: 'GET', method: "GET",
headers: headers headers: headers,
}); });
let data = await response.json(); let data = await response.json();
return data; return data;
@ -120,14 +130,13 @@ function sendReencryptedMessages(chatMessageDTOs) {
// console.log("Token = " + btoa("hmm" + ":" + "hmm")) // console.log("Token = " + btoa("hmm" + ":" + "hmm"))
// headers.append('Accept','application/json') // headers.append('Accept','application/json')
headers.append('Content-Type', 'application/json'); headers.append("Content-Type", "application/json");
headers.append('Authorization', authToken); headers.append("Authorization", authToken);
fetch(reencryptURL, { fetch(reencryptURL, {
method: 'POST', method: "POST",
headers: headers, headers: headers,
body: chatMessageDTOs body: chatMessageDTOs,
}) }).then((response) => console.log(response));
.then(response => console.log(response));
} }
handleAddToAdminForm(); handleAddToAdminForm();

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,10 @@
<title id="pageTitle">Change Passphrase</title> <title id="pageTitle">Change Passphrase</title>
</div> </div>
<script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script> <script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script>
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js" data-template-prefix="../" defer="defer" th:if="false"></script> <script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js"
<script th:src="@{/js/admin.js}" src="../../static/js/admin.js" defer="defer"></script> data-template-prefix="../" defer="defer" th:if="false"></script>
<!-- <script th:src="@{/js/admin.js}" src="../../static/js/admin.js" defer="defer"></script> -->
<script th:src="@{/js/adminBundle.js}" src="../../static/js/adminBundle.js" defer="defer"></script>
<script th:src="@{/js/sb-admin-2.js}" src="../../static/js/sb-admin-2.js" defer="defer"></script> <script th:src="@{/js/sb-admin-2.js}" src="../../static/js/sb-admin-2.js" defer="defer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js"></script>
@ -45,7 +47,8 @@
<!-- Page Heading --> <!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4"> <div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-light">Dashboard</h1> <h1 class="h3 mb-0 text-light">Dashboard</h1>
<a href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-download fa-sm text-white-50"></i> Generate Report</a> <a href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i
class="fas fa-download fa-sm text-white-50"></i> Generate Report</a>
</div> </div>
<!-- Content Row --> <!-- Content Row -->
@ -65,8 +68,7 @@
<label for="changePassphraseDropDown">Select User:</label> <label for="changePassphraseDropDown">Select User:</label>
<select class="form-control" id="changePassphraseDropDown"> <select class="form-control" id="changePassphraseDropDown">
<option th:each="userName : ${userNames}" <option th:each="userName : ${userNames}" th:value="${userName}"
th:value="${userName}"
th:text="#{${userName}}"> th:text="#{${userName}}">
Wireframe Wireframe
</option> </option>