temp commit
This commit is contained in:
parent
e06d98752a
commit
140721b542
@ -55,6 +55,7 @@
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
10
src/main/frontend/admin/main.ts
Normal file
10
src/main/frontend/admin/main.ts
Normal 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);
|
||||
});
|
96
src/main/frontend/admin/pages/user/ChangePassphrase.ts
Normal file
96
src/main/frontend/admin/pages/user/ChangePassphrase.ts
Normal 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));
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Model } from "../../common/model/AbstractModel";
|
||||
import { Model } from "../model/AbstractModel";
|
||||
|
||||
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.
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Controller } from "./AbstractController";
|
||||
import "../../common/model/AbstractModel"
|
||||
import "../../common/model/UserModel"
|
||||
import "../model/AbstractModel"
|
||||
import "../model/UserModel"
|
||||
import "../view/AbstractView"
|
||||
import "../view/UserView"
|
||||
import { Model } from "../../common/model/AbstractModel";
|
||||
import { Model } from "../model/AbstractModel";
|
||||
import { View } from "../view/AbstractView";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatModel } from "../../common/model/ChatModel";
|
||||
import { ChatModel } from "../model/ChatModel";
|
||||
import { ChatView } from "../view/ChatView";
|
||||
|
||||
export class ChatController {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Controller } from "./AbstractController";
|
||||
import "../../common/model/AbstractModel"
|
||||
import "../../common/model/UserModel"
|
||||
import "../model/AbstractModel"
|
||||
import "../model/UserModel"
|
||||
import "../view/AbstractView"
|
||||
import "../view/UserView"
|
||||
import { Model } from "../../common/model/AbstractModel";
|
||||
import { Model } from "../model/AbstractModel";
|
||||
import { View } from "../view/AbstractView";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { UserView } from "../view/UserView";
|
||||
import { UserModel } from "../../common/model/UserModel";
|
||||
import { UserModel } from "../model/UserModel";
|
||||
|
||||
export class UserController {
|
||||
private _model: UserModel;
|
||||
|
@ -3,15 +3,15 @@ import * as Handlebars from "handlebars";
|
||||
import * as log from "loglevel";
|
||||
import { ChatController } from "./controller/ChatController";
|
||||
import { UserController } from "./controller/UserController";
|
||||
import { ChatModel } from "../common/model/ChatModel";
|
||||
import { ChatModelHelper } from "../common/model/ChatModelHelper";
|
||||
import { UserModel } from "../common/model/UserModel";
|
||||
import { AlertifyNotificationService } from "./service/AlertifyNotificationService";
|
||||
import { EncryptionServiceFactory } from "./service/EncryptionServiceFactory";
|
||||
import { FuseSearchService } from "./service/FuseSearchService";
|
||||
import { MarkDownItMarkDownService } from "./service/MarkDownItMarkDownService";
|
||||
import { NotificationService } from "./service/NotificationService";
|
||||
import { SearchService } from "./service/SearchService";
|
||||
import { ChatModel } from "./model/ChatModel";
|
||||
import { ChatModelHelper } from "./model/ChatModelHelper";
|
||||
import { UserModel } from "./model/UserModel";
|
||||
import { AlertifyNotificationService } from "../common/service/AlertifyNotificationService";
|
||||
import { EncryptionServiceFactory } from "../common/service/EncryptionServiceFactory";
|
||||
import { FuseSearchService } from "../common/service/FuseSearchService";
|
||||
import { MarkDownItMarkDownService } from "../common/service/MarkDownItMarkDownService";
|
||||
import { NotificationService } from "../common/service/NotificationService";
|
||||
import { SearchService } from "../common/service/SearchService";
|
||||
import { TemplateFactory } from "./template/TemplateFactory";
|
||||
import { ChatView } from "./view/ChatView";
|
||||
import { ChatViewDeps } from "./view/ChatViewDeps";
|
||||
|
7
src/main/frontend/chat/model/AbstractModel.ts
Normal file
7
src/main/frontend/chat/model/AbstractModel.ts
Normal 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;
|
||||
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Subject } from "../../chat/observe/Observable";
|
||||
import { Observer } from "../../chat/observe/Observer";
|
||||
import { JsonAPI } from "../../chat/singleton/JsonAPI";
|
||||
import { ChatMessageViewModel } from "../../chat/viewmodel/ChatMessageViewModel";
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatModelHelper } from "./ChatModelHelper";
|
||||
import log = require("loglevel");
|
||||
import { ObserverData } from "../../chat/observe/ObserverData";
|
||||
import { ActiveUserViewModel } from "../../chat/viewmodel/ActiveUserViewModel";
|
||||
import { ObserverData } from "../observe/ObserverData";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import moment = require("moment");
|
||||
|
||||
interface Params {
|
@ -1,10 +1,10 @@
|
||||
import * as log from "loglevel";
|
||||
import { ChatMessageDTO } from "../../chat/dto/ChatMessageDTO";
|
||||
import { EncryptionService } from "../service/EncryptionService";
|
||||
import { NotificationService } from "../../chat/service/NotificationService";
|
||||
import { JsonAPI } from "../../chat/singleton/JsonAPI";
|
||||
import { Sprintf } from "../../chat/singleton/Sprintf";
|
||||
import { ChatMessageViewModel } from "../../chat/viewmodel/ChatMessageViewModel";
|
||||
import { ChatMessageDTO } from "../../common/dto/ChatMessageDTO";
|
||||
import { EncryptionService } from "../../common/service/EncryptionService";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { Sprintf } from "../../common/global/Sprintf";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
|
||||
export class ChatModelHelper {
|
||||
@ -145,7 +145,12 @@ export class ChatModelHelper {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
@ -1,6 +1,6 @@
|
||||
import log = require("loglevel");
|
||||
import { NotificationService } from "../../chat/service/NotificationService";
|
||||
import { Sprintf } from "../../chat/singleton/Sprintf";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { Sprintf } from "../../common/global/Sprintf";
|
||||
// import { sprintf } from "sprintf-js";
|
||||
///<reference path="../SprintfTest.d.ts" />
|
||||
|
@ -1,10 +1,10 @@
|
||||
import * as log from "loglevel";
|
||||
import { Subject } from "../../chat/observe/Observable";
|
||||
import { Observer } from "../../chat/observe/Observer";
|
||||
import { JsonAPI } from "../../chat/singleton/JsonAPI";
|
||||
import { ActiveUserViewModel } from "../../chat/viewmodel/ActiveUserViewModel";
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
import { NotificationService } from "../../chat/service/NotificationService";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
|
||||
export class UserModel implements Subject<ActiveUserViewModel> {
|
||||
/**
|
@ -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.
|
||||
import { Model } from "../../common/model/AbstractModel";
|
||||
import { Model } from "../model/AbstractModel";
|
||||
import { Controller } from "../controller/AbstractController";
|
||||
import { Observer } from "../observe/Observer";
|
||||
export interface View extends Observer<any> {
|
||||
|
@ -1,18 +1,18 @@
|
||||
import * as DOMPurify from "dompurify";
|
||||
import * as log from "loglevel";
|
||||
import { ChatMessageDTO } from "../dto/ChatMessageDTO";
|
||||
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
|
||||
import { ChatModel } from "../../common/model/ChatModel";
|
||||
import { ChatMessageDTO } from "../../common/dto/ChatMessageDTO";
|
||||
import { MessageCipherDTO } from "../../common/dto/MessageCipherDTO";
|
||||
import { ChatModel } from "../model/ChatModel";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { EncryptionService } from "../../common/service/EncryptionService";
|
||||
import { MarkDownService } from "../service/MarkDownService";
|
||||
import { MarkDownService } from "../../common/service/MarkDownService";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatViewDeps } from "./ChatViewDeps";
|
||||
import { fetchHandler } from "./FetchHandler";
|
||||
import { ObserverData } from "../observe/ObserverData";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { UserModel } from "../../common/model/UserModel";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { UserModel } from "../model/UserModel";
|
||||
|
||||
export class ChatView implements Observer<ChatMessageViewModel> {
|
||||
private readonly _chatModel: ChatModel;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatModel } from "../../common/model/ChatModel";
|
||||
import { MarkDownService } from "../service/MarkDownService";
|
||||
import { ChatModel } from "../model/ChatModel";
|
||||
import { MarkDownService } from "../../common/service/MarkDownService";
|
||||
import { EncryptionService } from "../../common/service/EncryptionService";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { UserModel } from "../../common/model/UserModel";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { UserModel } from "../model/UserModel";
|
||||
|
||||
export interface ChatViewDeps {
|
||||
chatModel: ChatModel;
|
||||
|
@ -1,34 +1,53 @@
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { Sprintf } from "../singleton/Sprintf";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { Sprintf } from "../../common/global/Sprintf";
|
||||
|
||||
export function fetchHandler(response: Response, ns: NotificationService) {
|
||||
if (response.ok) {
|
||||
return response.json().then((json: any) => {
|
||||
// the status was ok and there is a json body
|
||||
// return Promise.resolve({ json: json, response: response });
|
||||
ns.success('Message sent succesfully' + Sprintf(" (http code %d)", response.status));
|
||||
}).catch((err: any) => {
|
||||
// the status was ok but there is no json body
|
||||
// return Promise.resolve({ response: response });
|
||||
ns.success('Message sent succesfully' + Sprintf(" (http code %d)", response.status));
|
||||
if (response.ok) {
|
||||
return response
|
||||
.json()
|
||||
.then((json: any) => {
|
||||
// the status was ok and there is a json body
|
||||
// return Promise.resolve({ json: json, response: response });
|
||||
ns.success(
|
||||
"Message sent succesfully" +
|
||||
Sprintf(" (http code %d)", response.status)
|
||||
);
|
||||
})
|
||||
.catch((err: any) => {
|
||||
// the status was ok but there is no json body
|
||||
// return Promise.resolve({ response: response });
|
||||
ns.success(
|
||||
"Message sent succesfully" +
|
||||
Sprintf(" (http code %d)", response.status)
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return response
|
||||
.json()
|
||||
.catch((err: any) => {
|
||||
// the status was not ok and there is no json body
|
||||
// throw new Error(response.statusText);
|
||||
ns.error("Some error occured. Please try again.");
|
||||
})
|
||||
.then((json: any) => {
|
||||
// the status was not ok but there is a json body
|
||||
// throw new Error(json.error.message); // example error message returned by a REST
|
||||
// let delay = alertify.get('notifier', 'delay');
|
||||
// alertify.set('notifier', 'delay', 30);
|
||||
let errorMessage = "";
|
||||
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
|
||||
);
|
||||
});
|
||||
|
||||
} else {
|
||||
return response.json().catch((err: any) => {
|
||||
// the status was not ok and there is no json body
|
||||
// throw new Error(response.statusText);
|
||||
ns.error('Some error occured. Please try again.');
|
||||
}).then((json: any) => {
|
||||
// the status was not ok but there is a json body
|
||||
// throw new Error(json.error.message); // example error message returned by a REST
|
||||
// let delay = alertify.get('notifier', 'delay');
|
||||
// alertify.set('notifier', 'delay', 30);
|
||||
let errorMessage = "";
|
||||
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);
|
||||
});
|
||||
ns.errorWithDelay(Sprintf('There were errors in your message - %s', errorMessage), 30);
|
||||
// alertify.set('notifier', 'delay', delay);
|
||||
});
|
||||
}
|
||||
ns.errorWithDelay(
|
||||
Sprintf("There were errors in your message - %s", errorMessage),
|
||||
30
|
||||
);
|
||||
// alertify.set('notifier', 'delay', delay);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { ChatModel } from "../../common/model/ChatModel";
|
||||
import { ChatModel } from "../model/ChatModel";
|
||||
import log = require("loglevel");
|
||||
import * as DOMPurify from "dompurify";
|
||||
import { SearchService } from "../service/SearchService";
|
||||
import { UserModel } from "../../common/model/UserModel";
|
||||
import { SearchService } from "../../common/service/SearchService";
|
||||
import { UserModel } from "../model/UserModel";
|
||||
import { UserViewDeps } from "./UserViewDeps";
|
||||
import { ObserverData } from "../observe/ObserverData";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
|
||||
export class UserView implements Observer<ActiveUserViewModel> {
|
||||
|
@ -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 { NotificationService } from "../service/NotificationService";
|
||||
import { NotificationService } from "../../common/service/NotificationService";
|
||||
|
||||
export interface UserViewDeps {
|
||||
model: UserModel;
|
||||
|
16
src/main/frontend/common/dto/ReencryptionDTO.ts
Normal file
16
src/main/frontend/common/dto/ReencryptionDTO.ts
Normal 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;
|
||||
}
|
5
src/main/frontend/common/entity/MessageCipher.ts
Normal file
5
src/main/frontend/common/entity/MessageCipher.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
|
||||
|
||||
export interface MessageCipher extends MessageCipherDTO {
|
||||
id: number;
|
||||
}
|
4
src/main/frontend/common/global/Credentials.ts
Normal file
4
src/main/frontend/common/global/Credentials.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export namespace Credentials {
|
||||
export const principleName: string = localStorage.getItem("username") || "";
|
||||
export const authToken: string = localStorage.getItem("authToken") || "";
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
5
src/main/frontend/common/routes/Admin.ts
Normal file
5
src/main/frontend/common/routes/Admin.ts
Normal 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`;
|
||||
}
|
0
src/main/frontend/common/routes/Chat.ts
Normal file
0
src/main/frontend/common/routes/Chat.ts
Normal file
5
src/main/frontend/common/routes/Routes.ts
Normal file
5
src/main/frontend/common/routes/Routes.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { Admin as _admin } from "./Admin";
|
||||
|
||||
export namespace Routes {
|
||||
export const Admin = _admin;
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import { MessageCipherDTO } from "../../chat/dto/MessageCipherDTO";
|
||||
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
|
||||
|
||||
export interface EncryptionService {
|
||||
encrypt(passphrase: string, plainText: string): any;
|
||||
decrypt(passphrase: string, cipher: MessageCipherDTO): string;
|
||||
decryptAsPromise(passphrase: string, cipher: MessageCipherDTO): Promise<string>
|
||||
encrypt(passphrase: string, plainText: string): MessageCipherDTO;
|
||||
decrypt(passphrase: string, cipher: MessageCipherDTO): string;
|
||||
decryptAsPromise(
|
||||
passphrase: string,
|
||||
cipher: MessageCipherDTO
|
||||
): Promise<string>;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { EncryptionService } from "../../common/service/EncryptionService";
|
||||
import { SJCLEncryptionService } from "../../common/service/SJCLEncryptionService";
|
||||
import { EncryptionService } from "./EncryptionService";
|
||||
import { SJCLEncryptionService } from "./SJCLEncryptionService";
|
||||
// import PromiseWorker = require('promise-worker');
|
||||
import PromiseWorker from "promise-worker";
|
||||
|
@ -1,32 +1,41 @@
|
||||
import { EncryptionService } from "./EncryptionService";
|
||||
import * as sjcl from "sjcl";
|
||||
import { MessageCipherDTO } from "../../chat/dto/MessageCipherDTO";
|
||||
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
|
||||
import PromiseWorker from "promise-worker";
|
||||
export class SJCLEncryptionService implements EncryptionService {
|
||||
private _params: sjcl.SjclCipherParams = { mode: "gcm", ts: 128, adata: "", iter: 10000 };
|
||||
private readonly _promiseWorker: PromiseWorker;
|
||||
private _params: sjcl.SjclCipherParams = {
|
||||
mode: "gcm",
|
||||
ts: 128,
|
||||
adata: "",
|
||||
iter: 10000,
|
||||
};
|
||||
private readonly _promiseWorker: PromiseWorker;
|
||||
|
||||
constructor(promiseWorker: PromiseWorker) {
|
||||
this._promiseWorker = promiseWorker;
|
||||
}
|
||||
constructor(promiseWorker: PromiseWorker) {
|
||||
this._promiseWorker = promiseWorker;
|
||||
}
|
||||
|
||||
public encrypt(passphrase: string, plainText: string): MessageCipherDTO {
|
||||
const fn = () => {
|
||||
// @ts-ignore
|
||||
const cipher = sjcl.encrypt(passphrase, plainText, this._params);
|
||||
return (cipher as unknown) as string;
|
||||
};
|
||||
return JSON.parse(fn());
|
||||
}
|
||||
|
||||
public decrypt(passphrase: string, cipher: MessageCipherDTO): string {
|
||||
return sjcl.decrypt(passphrase, JSON.stringify(cipher));
|
||||
}
|
||||
|
||||
public encrypt(passphrase: string, plainText: string): MessageCipherDTO {
|
||||
const fn = () => {
|
||||
// @ts-ignore
|
||||
const cipher = sjcl.encrypt(passphrase, plainText, this._params)
|
||||
return cipher as unknown as string
|
||||
}
|
||||
return JSON.parse(fn())
|
||||
}
|
||||
|
||||
public decrypt(passphrase: string, cipher: MessageCipherDTO): string {
|
||||
return sjcl.decrypt(passphrase, JSON.stringify(cipher));
|
||||
}
|
||||
|
||||
public async decryptAsPromise(passphrase: string, cipher: MessageCipherDTO): Promise<string> {
|
||||
const decrypted = await this._promiseWorker.postMessage({ "passphrase": passphrase, "cipher": cipher })
|
||||
return decrypted;
|
||||
}
|
||||
public async decryptAsPromise(
|
||||
passphrase: string,
|
||||
cipher: MessageCipherDTO
|
||||
): Promise<string> {
|
||||
const decrypted = await this._promiseWorker.postMessage<
|
||||
string,
|
||||
{ passphrase: string; cipher: MessageCipherDTO }
|
||||
>({ passphrase: passphrase, cipher: cipher });
|
||||
return decrypted;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import registerPromiseWorker from 'promise-worker/register';
|
||||
import * as sjcl from 'sjcl'
|
||||
import { MessageCipherDTO } from '../../chat/dto/MessageCipherDTO';
|
||||
import { MessageCipherDTO } from '../../common/dto/MessageCipherDTO';
|
||||
|
||||
|
||||
registerPromiseWorker((payload: { passphrase: string, cipher: MessageCipherDTO }) => {
|
||||
|
@ -51,11 +51,16 @@ public class AdminRESTController {
|
||||
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
|
||||
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName,
|
||||
@PathVariable Instant lastMessageTime, Principal principal) {
|
||||
List<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(
|
||||
principal.getName(), userName, lastMessageTime);
|
||||
List<ChatMessageDTO> chatMessageDTOs = chatService
|
||||
.getNewMessages(principal.getName(), userName, lastMessageTime);
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@GetMapping("/regular-users")
|
||||
public List<String> getAllRegularUsers() {
|
||||
return userService.getAllRegularUsers();
|
||||
}
|
||||
|
||||
@GetMapping("/get/users")
|
||||
public List<String> getAllOtherUsers(Principal principal) {
|
||||
return userService.findAllOtherUsers(principal.getName());
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.ros.chatto.dto;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
@ -14,10 +14,10 @@ import lombok.Data;
|
||||
public class ReencryptionDTO {
|
||||
@NotBlank(message = "Username should not be blank")
|
||||
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "Username must be alphanumeric")
|
||||
@Size(max=15)
|
||||
@Size(max = 15)
|
||||
private String toUser, fromUser;
|
||||
@NotBlank
|
||||
@Size(max=600)
|
||||
@Size(max = 600)
|
||||
private MessageCipher messageCipher;
|
||||
private Date messageTime;
|
||||
private Instant messageTime;
|
||||
}
|
||||
|
@ -1,133 +1,142 @@
|
||||
console.log('Hello world!');
|
||||
console.log("Hello world!");
|
||||
|
||||
var getAllMessagesURL = `http://${hostAddress}/api/admin/get/messages/`; //hostAddress set in thymeleaf backend
|
||||
var reencryptURL = `http://${hostAddress}/api/admin/post/re-encrypt`;
|
||||
var getAllRegularUsersURL = `http://${hostAddress}/api/regular-users`;
|
||||
var username = sessionStorage.getItem('username');
|
||||
var password = sessionStorage.getItem('password');
|
||||
var authToken = 'Basic ' + btoa(username + ":" + password);
|
||||
var username = sessionStorage.getItem("username");
|
||||
var password = sessionStorage.getItem("password");
|
||||
var authToken = "Basic " + btoa(username + ":" + password);
|
||||
var iterations = 10000;
|
||||
|
||||
function handleAddToAdminForm() {
|
||||
document.getElementById('addUserToAdminForm').addEventListener(
|
||||
'submit',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
getAllRegularUsers()
|
||||
// .then(usernamesArray => {
|
||||
// console.lo
|
||||
// });
|
||||
});
|
||||
document
|
||||
.getElementById("addUserToAdminForm")
|
||||
.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
getAllRegularUsers();
|
||||
// .then(usernamesArray => {
|
||||
// console.lo
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
function handleChangePassphraseForm() {
|
||||
document.getElementById('changePassphraseForm').addEventListener(
|
||||
'submit',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
let changePassphraseDropDown = document.getElementById('changePassphraseDropDown');
|
||||
let user = changePassphraseDropDown.value;
|
||||
let passphraseOld = document.getElementById('passphraseOld');
|
||||
let passphraseNew = document.getElementById('passphraseNew');
|
||||
// let messageCipherNew = {};
|
||||
console.log(user);
|
||||
getAllMessages(user)
|
||||
.then(json => {
|
||||
console.log(json);
|
||||
document
|
||||
.getElementById("changePassphraseForm")
|
||||
.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
let changePassphraseDropDown = document.getElementById(
|
||||
"changePassphraseDropDown"
|
||||
);
|
||||
let user = changePassphraseDropDown.value;
|
||||
let passphraseOld = document.getElementById("passphraseOld");
|
||||
let passphraseNew = document.getElementById("passphraseNew");
|
||||
// let messageCipherNew = {};
|
||||
console.log(user);
|
||||
getAllMessages(user)
|
||||
.then((json) => {
|
||||
console.log(json);
|
||||
|
||||
return json;
|
||||
})
|
||||
.then(json => {
|
||||
let jsonNew = [];
|
||||
let messageCiphers = [];
|
||||
let chatMessageDTOs = [];
|
||||
if (json.length > 0) {
|
||||
json.forEach(function(obj) {
|
||||
let newObj = obj;
|
||||
let messageID = obj.messageCipher.id;
|
||||
let plainText = sjcl.decrypt(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 messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||
// console.log(messageCipherNew)
|
||||
let messageCipherNewObj = JSON.parse(messageCipherNew);
|
||||
// console.log(messageCipherNewObj);
|
||||
messageCipherNewObj.id = messageID;
|
||||
newObj.messageCipher = messageCipherNewObj;
|
||||
// obj.messageCipher = messageCipherNewObj;
|
||||
// console.log(obj.messageCipher);
|
||||
// console.log(plainText);
|
||||
// console.log(messageCipherNewObj);
|
||||
jsonNew.push(newObj);
|
||||
messageCiphers.push(messageCipherNewObj);
|
||||
return json;
|
||||
})
|
||||
.then((json) => {
|
||||
let jsonNew = [];
|
||||
let messageCiphers = [];
|
||||
let chatMessageDTOs = [];
|
||||
if (json.length > 0) {
|
||||
json.forEach(function (obj) {
|
||||
let newObj = obj;
|
||||
let messageID = obj.messageCipher.id;
|
||||
let plainText = sjcl.decrypt(
|
||||
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 messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||
// console.log(messageCipherNew)
|
||||
let messageCipherNewObj = JSON.parse(messageCipherNew);
|
||||
// console.log(messageCipherNewObj);
|
||||
messageCipherNewObj.id = messageID;
|
||||
newObj.messageCipher = messageCipherNewObj;
|
||||
// obj.messageCipher = messageCipherNewObj;
|
||||
// console.log(obj.messageCipher);
|
||||
// console.log(plainText);
|
||||
// console.log(messageCipherNewObj);
|
||||
jsonNew.push(newObj);
|
||||
messageCiphers.push(messageCipherNewObj);
|
||||
|
||||
// let messageCipherJson = JSON.stringify(messageCipherNewObj);
|
||||
let chatMessageDTO = {
|
||||
"toUser": user,
|
||||
"fromUser": username,
|
||||
"messageCipher": messageCipherNewObj
|
||||
}
|
||||
chatMessageDTOs.push(chatMessageDTO);
|
||||
});
|
||||
// console.log(jsonNew);
|
||||
// let messageCipherJson = JSON.stringify(messageCipherNewObj);
|
||||
let chatMessageDTO = {
|
||||
toUser: user,
|
||||
fromUser: username,
|
||||
messageCipher: messageCipherNewObj,
|
||||
};
|
||||
chatMessageDTOs.push(chatMessageDTO);
|
||||
});
|
||||
// console.log(jsonNew);
|
||||
}
|
||||
// sendReencryptedMessages(JSON.stringify(jsonNew));
|
||||
console.log;
|
||||
sendReencryptedMessages(JSON.stringify(chatMessageDTOs));
|
||||
// sendReencryptedMessages(JSON.stringify(messageCiphers));
|
||||
|
||||
}
|
||||
// sendReencryptedMessages(JSON.stringify(jsonNew));
|
||||
console.log
|
||||
sendReencryptedMessages(JSON.stringify(chatMessageDTOs));
|
||||
// sendReencryptedMessages(JSON.stringify(messageCiphers));
|
||||
|
||||
return jsonNew;
|
||||
})
|
||||
.then(json => {
|
||||
json.forEach(function(obj) {
|
||||
let plainText = sjcl.decrypt("password2", JSON.stringify(obj.messageCipher));
|
||||
console.log(plainText);
|
||||
})
|
||||
|
||||
});
|
||||
return jsonNew;
|
||||
})
|
||||
.then((json) => {
|
||||
json.forEach(function (obj) {
|
||||
let plainText = sjcl.decrypt(
|
||||
"password2",
|
||||
JSON.stringify(obj.messageCipher)
|
||||
);
|
||||
console.log(plainText);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function getAllMessages(user) {
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append('Authorization', authToken);
|
||||
let response = await fetch(`${getAllMessagesURL}${user}`, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append("Authorization", authToken);
|
||||
let response = await fetch(`${getAllMessagesURL}${user}`, {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
async function getAllRegularUsers() {
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append('Authorization', authToken);
|
||||
let response = await fetch(`${getAllRegularUsersURL}`, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append("Authorization", authToken);
|
||||
let response = await fetch(`${getAllRegularUsersURL}`, {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
function sendReencryptedMessages(chatMessageDTOs) {
|
||||
let headers = new Headers();
|
||||
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
|
||||
let headers = new Headers();
|
||||
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
|
||||
|
||||
// headers.append('Accept','application/json')
|
||||
headers.append('Content-Type', 'application/json');
|
||||
headers.append('Authorization', authToken);
|
||||
fetch(reencryptURL, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: chatMessageDTOs
|
||||
})
|
||||
.then(response => console.log(response));
|
||||
// headers.append('Accept','application/json')
|
||||
headers.append("Content-Type", "application/json");
|
||||
headers.append("Authorization", authToken);
|
||||
fetch(reencryptURL, {
|
||||
method: "POST",
|
||||
headers: headers,
|
||||
body: chatMessageDTOs,
|
||||
}).then((response) => console.log(response));
|
||||
}
|
||||
|
||||
handleAddToAdminForm();
|
||||
|
22831
src/main/resources/static/js/adminBundle.js
Normal file
22831
src/main/resources/static/js/adminBundle.js
Normal file
File diff suppressed because one or more lines are too long
@ -6,8 +6,10 @@
|
||||
<title id="pageTitle">Change Passphrase</title>
|
||||
</div>
|
||||
<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 th:src="@{/js/admin.js}" src="../../static/js/admin.js" defer="defer"></script>
|
||||
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js"
|
||||
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 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>
|
||||
@ -45,7 +47,8 @@
|
||||
<!-- Page Heading -->
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<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>
|
||||
|
||||
<!-- Content Row -->
|
||||
@ -65,13 +68,12 @@
|
||||
<label for="changePassphraseDropDown">Select User:</label>
|
||||
<select class="form-control" id="changePassphraseDropDown">
|
||||
|
||||
<option th:each="userName : ${userNames}"
|
||||
th:value="${userName}"
|
||||
th:text="#{${userName}}">
|
||||
Wireframe
|
||||
</option>
|
||||
<option th:each="userName : ${userNames}" th:value="${userName}"
|
||||
th:text="#{${userName}}">
|
||||
Wireframe
|
||||
</option>
|
||||
|
||||
</select>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
Loading…
Reference in New Issue
Block a user