2
0
mirror of https://github.com/esiur/esiur-js.git synced 2025-05-06 04:22:58 +00:00
esiur-js/demo/chat/chat.js
2024-06-24 19:45:19 +03:00

174 lines
5.9 KiB
JavaScript

import Warehouse from "../../src/Resource/Warehouse.js";
import { createRequire } from 'module'
import AsyncReply from "../../src/Core/AsyncReply.js";
import DistributedServer from "../../src/Net/IIP/DistributedServer.js";
import IMembership from "../../src/Security/Membership/IMembership.js";
import AuthorizationResults from "../../src/Security/Membership/AuthorizationResults.js";
import WSocket from "../../src/Net/Sockets/WSocket.js";
import MemoryStore from "../../src/Stores/MemoryStore.js";
import DC from "../../src/Data/DC.js";
import IResource from "../../src/Resource/IResource.js";
import TransmissionType, { TransmissionTypeIdentifier } from "../../src/Data/TransmissionType.js";
import TypedMap from "../../src/Data/TypedMap.js";
import { Arg, Evt, Func, Prop, TemplateDescriber } from "../../src/Resource/Template/TemplateDescriber.js";
import { Int32 } from "../../src/Data/ExtendedTypes.js";
import AuthorizationResultsResponse from "../../src/Security/Membership/AuthorizationResultsResponse.js";
import IIPAuthPacketIAuthDestination from '../../src/Net/Packets/IIPAuthPacketIAuthDestination.js';
import IIPAuthPacketIAuthFormat from '../../src/Net/Packets/IIPAuthPacketIAuthFormat.js';
import IIPAuthPacketHeader from '../../src/Net/Packets/IIPAuthPacketHeader.js';
import Codec from '../../src/Data/Codec.js';
import BinaryList from "../../src/Data/BinaryList.js";
import SHA256 from "../../src/Security/Integrity/SHA256.js";
const require = createRequire(import.meta.url);
const WebSocket = require('ws');
const http = require("http");
const fs = require("fs");
const wss = new WebSocket.Server({port: 8001});
class MyMembership extends IMembership {
userExists(username, domain) {
return new AsyncReply(username);
}
getPassword(username, domain) {
return new AsyncReply(DC.stringToBytes("1234"));
}
authorize(session){
let results = new AuthorizationResults();
if (session.authorizedAccount == "admin")
{
results.clue = "What is 5 + 2 ?";
results.destination = IIPAuthPacketIAuthDestination.Self;
results.requiredFormat = IIPAuthPacketIAuthFormat.Number;
results.response = AuthorizationResultsResponse.IAuthHashed;
results.expire = new Date(new Date().getTime() + 30000);
results.reference = Math.round(Math.random() * 100000);
}
else if (session.authorizedAccount == "demo")
{
results.clue = "What is 10 * 2 ?";
results.destination = IIPAuthPacketIAuthDestination.Self;
results.requiredFormat = IIPAuthPacketIAuthFormat.Number;
results.response = AuthorizationResultsResponse.IAuthPlain;
results.expire = new Date(new Date().getTime() + 30000);
results.reference = Math.round(Math.random() * 100000);
}
else {
results.response = AuthorizationResultsResponse.Success;
}
return new AsyncReply(results);
}
authorizeHashed(session, reference, algorithm, value){
// compute hash
let remoteNonce = session.remoteHeaders.get(IIPAuthPacketHeader.Nonce);
let localNonce = session.localHeaders.get(IIPAuthPacketHeader.Nonce);
// local nonce + password or token + remote nonce
var challenge = SHA256.compute(new BinaryList()
.addUint8Array(remoteNonce)
.addUint8Array(Codec.compose(7, null)) // answer is 7
.addUint8Array(localNonce)
.toArray());
if (challenge.sequenceEqual(value))
return new AsyncReply(new AuthorizationResults(AuthorizationResultsResponse.Success));
else
return new AsyncReply(new AuthorizationResults(AuthorizationResultsResponse.Failed));
}
authorizePlain(session, reference, value) {
if (value == 20)
return new AsyncReply(new AuthorizationResults(AuthorizationResultsResponse.Success));
else
return new AsyncReply(new AuthorizationResults(AuthorizationResultsResponse.Failed));
}
};
var server;
class MyChat extends IResource {
static get template() {
return new TemplateDescriber("Chat",[
new Prop("title", String), new Prop("messages", Array), new Prop("users", Array),
new Func("send", null, [new Arg("msg", String, true)]),
new Evt("message", Map), new Evt("voice", Int32, true), new Evt("login"), new Evt("logout")]
);
}
constructor() {
super();
this.messages = [new TypedMap({usr: "Admin", msg: "Welcome to Esiur", date: new Date()})];
this.title = "Chat Room";
}
get users() {
return server.connections.map(x=>x.session.authorizedAccount);
}
send(msg, sender)
{
let s = new TypedMap({ msg, usr: sender.session.authorizedAccount, date: new Date()});
this.messages.push(s);
this._emit("message", s);
}
query(path, sender) {
return new AsyncReply([this]);
}
}
let sys = await Warehouse.new(MemoryStore, "sys");
let ms = await Warehouse.new(MyMembership, "ms");
let chat = await Warehouse.new(MyChat, "chat", sys);
server = await Warehouse.new(DistributedServer, "dss", sys, null, null, {membership: ms, entryPoint: chat});
wss.on('connection', function connection(ws)
{
let con = server.add();
con.assign(new WSocket(ws));
con.on("ready", (x)=>{
chat._emit("login", x.session.authorizedAccount);
}).on("close", (x)=>{
chat._emit("logout", x.session.authorizedAccount);
});
});
http.createServer(function (req, res) {
fs.readFile("." + req.url, function (err,data) {
if (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
} else {
res.writeHead(200, {"Content-Type": req.url.split('.').pop() == "js" ? "text/javascript" : "text/html"});
res.end(data);
}
});
}).listen(8000);
console.log(`HTTP Server running http://localhost:8000/demo/chat/index.html`);
console.log(`IIP Server running iip://localhost:8001`);