2
0
mirror of https://github.com/esiur/esiur-js.git synced 2025-05-06 12:32:58 +00:00
This commit is contained in:
Ahmed Zamil 2024-06-23 14:10:30 +03:00
parent 408d2237f4
commit 5bd69baa71
11 changed files with 325 additions and 138 deletions

View File

@ -4,6 +4,7 @@ import { createRequire } from 'module'
import AsyncReply from "../../src/Core/AsyncReply.js"; import AsyncReply from "../../src/Core/AsyncReply.js";
import DistributedServer from "../../src/Net/IIP/DistributedServer.js"; import DistributedServer from "../../src/Net/IIP/DistributedServer.js";
import IMembership from "../../src/Security/Membership/IMembership.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 WSocket from "../../src/Net/Sockets/WSocket.js";
import MemoryStore from "../../src/Stores/MemoryStore.js"; import MemoryStore from "../../src/Stores/MemoryStore.js";
import DC from "../../src/Data/DC.js"; import DC from "../../src/Data/DC.js";
@ -13,6 +14,12 @@ import TypedMap from "../../src/Data/TypedMap.js";
import { Arg, Evt, Func, Prop, TemplateDescriber } from "../../src/Resource/Template/TemplateDescriber.js"; import { Arg, Evt, Func, Prop, TemplateDescriber } from "../../src/Resource/Template/TemplateDescriber.js";
import { Int32 } from "../../src/Data/ExtendedTypes.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';
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
@ -31,6 +38,64 @@ class MyMembership extends IMembership {
getPassword(username, domain) { getPassword(username, domain) {
return new AsyncReply(DC.stringToBytes("1234")); 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);
var hashFunc = SHA256.Create();
// local nonce + password or token + remote nonce
var challenge = hashFunc.ComputeHash(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; var server;
@ -53,12 +118,12 @@ class MyChat extends IResource {
} }
get users() { get users() {
return server.connections.map(x=>x.session.remoteAuthentication.username); return server.connections.map(x=>x.session.authorizedAccount);
} }
send(msg, sender) send(msg, sender)
{ {
let s = new TypedMap({ msg, usr: sender.session.remoteAuthentication.username, date: new Date()}); let s = new TypedMap({ msg, usr: sender.session.authorizedAccount, date: new Date()});
this.messages.push(s); this.messages.push(s);
this._emit("message", s); this._emit("message", s);
} }

View File

@ -6,6 +6,15 @@
var service; var service;
let $ = document.querySelector; let $ = document.querySelector;
function authenticator(x)
{
debugger;
let challenge = prompt(x.clue);
if (challenge != null) {
return new Esiur.Core.AsyncReply(parseInt(challenge));
}
}
async function connect(){ async function connect(){
let status = document.getElementById("status"); let status = document.getElementById("status");
@ -15,7 +24,7 @@
try { try {
status.innerHTML = "Connecting..."; status.innerHTML = "Connecting...";
service = await wh.get("iip://localhost:8001/chat", {username, password: "1234", autoReconnect: true}); service = await wh.get("iip://localhost:8001/sys/chat", {username, password: "1234", autoReconnect: true, authenticator: authenticator});
login.style.display = "none"; login.style.display = "none";
service.on("message", appendMessage) service.on("message", appendMessage)
.on(":title", updateTitle) .on(":title", updateTitle)

22
src/Misc/Global.js Normal file
View File

@ -0,0 +1,22 @@
export default class Global
{
static generateBytes(length){
var rt = new Uint8Array(length);
for (var i = 0; i < length; i++)
rt[i] = Math.random() * 255;
return rt;
}
static generateCode(length = 16) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let rt = "";
for (var i = 0; i < length; i++)
rt += chars[Math.round(Math.random() * chars.length)];
return rt;
}
}

View File

@ -91,6 +91,11 @@ import { UInt8 } from '../../Data/ExtendedTypes.js';
import ConnectionStatus from './ConnectionStatus.js'; import ConnectionStatus from './ConnectionStatus.js';
import { Prop, TemplateDescriber } from '../../Resource/Template/TemplateDescriber.js'; import { Prop, TemplateDescriber } from '../../Resource/Template/TemplateDescriber.js';
import TypedMap from '../../Data/TypedMap.js'; import TypedMap from '../../Data/TypedMap.js';
import Global from '../../Misc/Global.js';
import IIPAuthPacketHashAlgorithm from '../../Net/Packets/IIPAuthPacketHashAlgorithm.js';
import AuthorizationResultsResponse from '../../Security/Membership/AuthorizationResultsResponse.js';
import IIPAuthPacketIAuthHeader from '../../Net/Packets/IIPAuthPacketIAuthHeader.js';
import AuthorizationRequest from '../../Security/Membership/AuthorizationRequest.js';
export default class DistributedConnection extends IStore { export default class DistributedConnection extends IStore {
@ -100,7 +105,7 @@ export default class DistributedConnection extends IStore {
#secure; #secure;
#socket; #socket;
#lastKeepAliveSent #lastKeepAliveSent;
#lastKeepAliveReceived; #lastKeepAliveReceived;
#status; #status;
@ -123,7 +128,9 @@ export default class DistributedConnection extends IStore {
#loginDate; #loginDate;
jitter = 0; #jitter = 0;
keepAliveTime = 10; keepAliveTime = 10;
keepAliveInterval = 30; keepAliveInterval = 30;
@ -144,6 +151,10 @@ export default class DistributedConnection extends IStore {
#subscriptions = new Map(); #subscriptions = new Map();
#ready; #ready;
get jitter() {
return this.#jitter;
}
get session() { get session() {
return this.#session; return this.#session;
} }
@ -160,13 +171,9 @@ export default class DistributedConnection extends IStore {
return new SendList(this, doneReply); return new SendList(this, doneReply);
} }
#generateCode(length) {
var rt = new Uint8Array(length);
for (var i = 0; i < length; i++)
rt[i] = Math.random() * 255;
return rt;
}
constructor(server) { constructor(server) {
@ -174,6 +181,7 @@ export default class DistributedConnection extends IStore {
this.#session.authenticationType = AuthenticationType.Host; this.#session.authenticationType = AuthenticationType.Host;
this.#session.localMethod = AuthenticationMethod.None; this.#session.localMethod = AuthenticationMethod.None;
this.#session.localHeaders.set(IIPAuthPacketHeader.Nonce, Global.generateBytes(32));
this.#server = server; this.#server = server;
@ -192,6 +200,9 @@ export default class DistributedConnection extends IStore {
} }
}); });
// set local nonce
} }
@ -636,7 +647,7 @@ export default class DistributedConnection extends IStore {
} }
// start perodic keep alive timer // start perodic keep alive timer
this.#keepAliveTimer = setInterval(this.#keepAliveTimerElapsed, this.keepAliveInterval * 1000); this.#keepAliveTimer = setInterval(this.#keepAliveTimerElapsed.bind(this), this.keepAliveInterval * 1000);
} }
else if (authPacket.event == IIPAuthPacketEvent.IAuthPlain) else if (authPacket.event == IIPAuthPacketEvent.IAuthPlain)
@ -644,6 +655,7 @@ export default class DistributedConnection extends IStore {
let dataType = authPacket.dataType; let dataType = authPacket.dataType;
let pr = Codec.parse(data, dataType.offset, this, null, dataType); let pr = Codec.parse(data, dataType.offset, this, null, dataType);
let headers = pr.reply.result; let headers = pr.reply.result;
let iAuthRequest = new AuthorizationRequest(headers);
if (authenticator == null) if (authenticator == null)
@ -657,16 +669,15 @@ export default class DistributedConnection extends IStore {
} }
else else
{ {
this.authenticator(headers).then((response) => this.authenticator(iAuthRequest).then((response) =>
{ {
this.#sendParams() this.#sendParams()
.addUint8(IIPAuthPacketAction.IAuthPlain) .addUint8(IIPAuthPacketAction.IAuthPlain)
.addUint32(headers[IIPAuthPacketIAuthHeader.Reference]) .addUint32(headers.get(IIPAuthPacketIAuthHeader.Reference))
.addDC(Codec.compose(response, this)) .addDC(Codec.compose(response, this))
.done(); .done();
}) })
.timeout(headers.containsKey(IIPAuthPacketIAuthHeader.Timeout) ? .timeout(iAuthRequest.timeout * 1000,
headers[IIPAuthPacketIAuthHeader.Timeout] * 1000 : 30000,
() => { () => {
this.#sendParams() this.#sendParams()
.addUint8(IIPAuthPacketEvent.ErrorTerminate) .addUint8(IIPAuthPacketEvent.ErrorTerminate)
@ -683,6 +694,7 @@ export default class DistributedConnection extends IStore {
let dataType = authPacket.dataType; let dataType = authPacket.dataType;
let parsed = Codec.parse(data, dataType.offset, this, null, dataType); let parsed = Codec.parse(data, dataType.offset, this, null, dataType);
let headers = parsed.reply.result; let headers = parsed.reply.result;
let iAuthRequest = new AuthorizationRequest(headers);
if (this.authenticator == null) if (this.authenticator == null)
{ {
@ -695,7 +707,7 @@ export default class DistributedConnection extends IStore {
} }
else else
{ {
this.authenticator(headers).then((response) => this.authenticator(iAuthRequest).then((response) =>
{ {
var hash = SHA256.compute((BL() var hash = SHA256.compute((BL()
@ -706,14 +718,13 @@ export default class DistributedConnection extends IStore {
this.#sendParams() this.#sendParams()
.addUint8(IIPAuthPacketAction.IAuthHashed) .addUint8(IIPAuthPacketAction.IAuthHashed)
.addUint32(headers[IIPAuthPacketIAuthHeader.Reference]) .addUint32(headers.get(IIPAuthPacketIAuthHeader.Reference))
.addUint8(IIPAuthPacketHashAlgorithm.SHA256) .addUint8(IIPAuthPacketHashAlgorithm.SHA256)
.addUint16(hash.length) .addUint16(hash.length)
.addDC(hash) .addDC(hash)
.done(); .done();
}) })
.timeout(headers.containsKey(IIPAuthPacketIAuthHeader.Timeout) ? .timeout(iAuthRequest.timeout * 1000,
headers[IIPAuthPacketIAuthHeader.Timeout] * 1000 : 30000,
() => { () => {
this.#sendParams() this.#sendParams()
.addUint8(IIPAuthPacketEvent.ErrorTerminate) .addUint8(IIPAuthPacketEvent.ErrorTerminate)
@ -880,7 +891,7 @@ export default class DistributedConnection extends IStore {
{ {
let localHeaders = session.localHeaders; let localHeaders = session.localHeaders;
session.authorizedAccount = "g-" + this.#generateCode(); session.authorizedAccount = "g-" + Global.generateCode();
this.#readyToEstablish = true; this.#readyToEstablish = true;
@ -1067,20 +1078,14 @@ export default class DistributedConnection extends IStore {
{ {
if (results == null || results.response == AuthorizationResultsResponse.Success) if (results == null || results.response == AuthorizationResultsResponse.Success)
{ {
this.#session.id = Global.generateCode(32);
var r = new Random(); let accountId = DC.stringToBytes(this.#session.authorizedAccount);
var n = new DC(32);
for (var i = 0; i < 32; i++)
n[i] = r.nextInt(255);
session.id = n;
let accountId = DC.stringToBytes(session.authorizedAccount);
this.#sendParams() this.#sendParams()
.addUint8(IIPAuthPacketEvent.IndicationEstablished) .addUint8(IIPAuthPacketEvent.IndicationEstablished)
.addUint8(n.length) .addUint8(this.#session.id.length)
.addUint8Array(n) .addUint8Array(this.#session.id)
.addUint8(accountId.length) .addUint8(accountId.length)
.addUint8Array(accountId) .addUint8Array(accountId)
.done(); .done();
@ -1095,7 +1100,7 @@ export default class DistributedConnection extends IStore {
this.#openReply = null; this.#openReply = null;
this._emit("ready", this); this._emit("ready", this);
this.#server?.membership?.login(session); this.#server?.membership?.login(this.#session);
this.#loginDate = new Date(); this.#loginDate = new Date();
}).error((x) => }).error((x) =>
@ -1146,11 +1151,11 @@ export default class DistributedConnection extends IStore {
} }
else if (results.response == AuthorizationResultsResponse.IAuthPlain) else if (results.response == AuthorizationResultsResponse.IAuthPlain)
{ {
var args = new (TypedMap.of(Number, Object))([ var args = new (TypedMap.of(UInt8, Object))([
[IIPAuthPacketIAuthHeader.Reference, results.reference], [IIPAuthPacketIAuthHeader.Reference, results.reference],
[IIPAuthPacketIAuthHeader.Destination, results.destination], [IIPAuthPacketIAuthHeader.Destination, results.destination],
[IIPAuthPacketIAuthHeader.Timeout, results.timeout], [IIPAuthPacketIAuthHeader.Expire, results.expire],
[IIPAuthPacketIAuthHeader.Clue, results.clue], [IIPAuthPacketIAuthHeader.Clue, results.clue],
[IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat], [IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat],
]); ]);
@ -1167,7 +1172,7 @@ export default class DistributedConnection extends IStore {
[IIPAuthPacketIAuthHeader.Reference, results.reference], [IIPAuthPacketIAuthHeader.Reference, results.reference],
[IIPAuthPacketIAuthHeader.Destination, results.destination], [IIPAuthPacketIAuthHeader.Destination, results.destination],
[IIPAuthPacketIAuthHeader.Timeout, results.timeout], [IIPAuthPacketIAuthHeader.Expire, results.expire],
[IIPAuthPacketIAuthHeader.Clue, results.clue], [IIPAuthPacketIAuthHeader.Clue, results.clue],
[IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat], [IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat],
]); ]);
@ -1184,7 +1189,7 @@ export default class DistributedConnection extends IStore {
[IIPAuthPacketIAuthHeader.Reference, results.reference], [IIPAuthPacketIAuthHeader.Reference, results.reference],
[IIPAuthPacketIAuthHeader.Destination, results.destination], [IIPAuthPacketIAuthHeader.Destination, results.destination],
[IIPAuthPacketIAuthHeader.Timeout, results.timeout], [IIPAuthPacketIAuthHeader.Expire, results.expire],
[IIPAuthPacketIAuthHeader.Clue, results.clue], [IIPAuthPacketIAuthHeader.Clue, results.clue],
[IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat], [IIPAuthPacketIAuthHeader.RequiredFormat, results.requiredFormat],
]); ]);
@ -1345,9 +1350,11 @@ export default class DistributedConnection extends IStore {
autoReconnect = false, autoReconnect = false,
keepAliveInterval = 30, keepAliveInterval = 30,
keepAliveTime = 10, keepAliveTime = 10,
reconnectInterval = 5} = this.instance.attributes.toObject(); reconnectInterval = 5,
authenticator = null} = this.instance.attributes.toObject();
this.authenticator = authenticator;
this.debug = debug; this.debug = debug;
this.checkInterval = checkInterval * 1000; // check every 30 seconds this.checkInterval = checkInterval * 1000; // check every 30 seconds
this.connectionTimeout = connectionTimeout * 1000; // 10 minutes (4 pings failed) this.connectionTimeout = connectionTimeout * 1000; // 10 minutes (4 pings failed)
@ -1402,7 +1409,7 @@ export default class DistributedConnection extends IStore {
this.#session.remoteMethod = AuthenticationMethod.None; this.#session.remoteMethod = AuthenticationMethod.None;
this.#session.localHeaders.set(IIPAuthPacketHeader.Domain, domain); this.#session.localHeaders.set(IIPAuthPacketHeader.Domain, domain);
this.#session.localHeaders.set(IIPAuthPacketHeader.Nonce, this.#generateCode(32)); this.#session.localHeaders.set(IIPAuthPacketHeader.Nonce, Global.generateBytes(32));
if (method == AuthenticationMethod.Credentials) if (method == AuthenticationMethod.Credentials)
{ {
@ -1682,11 +1689,14 @@ export default class DistributedConnection extends IStore {
var reply = new AsyncReply(); var reply = new AsyncReply();
this.#callbackCounter++; this.#callbackCounter++;
this.#requests.set(this.#callbackCounter, reply); this.#requests.set(this.#callbackCounter, reply);
return this.this.#sendParams(reply).addUint8(0x40 | action).addUint32(this.#callbackCounter); return this.#sendParams(reply)
.addUint8(0x40 | action)
.addUint32(this.#callbackCounter);
} }
async detachResource(instanceId){ _sendDetachRequest(instanceId)
{
try try
{ {
if (this.#attachedResources.containsKey(instanceId)) if (this.#attachedResources.containsKey(instanceId))
@ -1695,19 +1705,9 @@ export default class DistributedConnection extends IStore {
if (this.#suspendedResources.containsKey(instanceId)) if (this.#suspendedResources.containsKey(instanceId))
this.#suspendedResources.remove(instanceId); this.#suspendedResources.remove(instanceId);
await this.#sendDetachRequest(instanceId); return this.#sendRequest(IIPPacketAction.DetachResource)
} .addUint32(instanceId)
catch .done();
{
}
}
#sendDetachRequest(instanceId)
{
try
{
return this.#sendRequest(IIPPacketAction.DetachResource).addUint32(instanceId).done();
} }
catch(ex) catch(ex)
{ {
@ -1715,13 +1715,14 @@ export default class DistributedConnection extends IStore {
} }
} }
#sendInvoke(instanceId, index, parameters) { _sendInvoke(instanceId, index, parameters) {
var reply = new AsyncReply(); var reply = new AsyncReply();
var pb = Codec.compose(parameters, this); var pb = Codec.compose(parameters, this);
let callbackId = ++this.#callbackCounter; let callbackId = ++this.#callbackCounter;
this.this.#sendParams() this.#sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunction) .addUint8(0x40 | IIPPacketAction.InvokeFunction)
.addUint32(callbackId) .addUint32(callbackId)
.addUint32(instanceId) .addUint32(instanceId)
@ -1734,17 +1735,28 @@ export default class DistributedConnection extends IStore {
return reply; return reply;
} }
_sendSetProperty(instanceId, index, value){
var cv = Codec.compose(value, this);
return this.#sendRequest(IIPPacketAction.SetProperty)
.addUint32(instanceId)
.addUint8(index)
.addUint8Array(cv)
.done()
}
#sendError(type, callbackId, errorCode, errorMessage = "") { #sendError(type, callbackId, errorCode, errorMessage = "") {
var msg = DC.stringToBytes(errorMessage); var msg = DC.stringToBytes(errorMessage);
if (type == ErrorType.Management) if (type == ErrorType.Management)
this.this.#sendParams() this.#sendParams()
.addUint8(0xC0 | IIPPacketReport.ManagementError) .addUint8(0xC0 | IIPPacketReport.ManagementError)
.addUint32(callbackId) .addUint32(callbackId)
.addUint16(errorCode) .addUint16(errorCode)
.done(); .done();
else if (type == ErrorType.Exception) else if (type == ErrorType.Exception)
this.this.#sendParams() this.#sendParams()
.addUint8(0xC0 | IIPPacketReport.ExecutionError) .addUint8(0xC0 | IIPPacketReport.ExecutionError)
.addUint32(callbackId) .addUint32(callbackId)
.addUint16(errorCode) .addUint16(errorCode)
@ -1754,7 +1766,7 @@ export default class DistributedConnection extends IStore {
} }
#sendProgress(callbackId, value, max) { #sendProgress(callbackId, value, max) {
this.this.#sendParams() this.#sendParams()
.addUint8(0xC0 | IIPPacketReport.ProgressReport) .addUint8(0xC0 | IIPPacketReport.ProgressReport)
.addUint32(callbackId) .addUint32(callbackId)
.addInt32(value) .addInt32(value)
@ -1764,7 +1776,7 @@ export default class DistributedConnection extends IStore {
#sendChunk(callbackId, chunk) { #sendChunk(callbackId, chunk) {
var c = Codec.compose(chunk, this); var c = Codec.compose(chunk, this);
this.this.#sendParams() this.#sendParams()
.addUint8(0xC0 | IIPPacketReport.ChunkStream) .addUint8(0xC0 | IIPPacketReport.ChunkStream)
.addUint32(callbackId) .addUint32(callbackId)
.addUint8Array(c) .addUint8Array(c)
@ -1851,12 +1863,12 @@ export default class DistributedConnection extends IStore {
// push to the queue to gaurantee serialization // push to the queue to gaurantee serialization
let item = new AsyncReply(); let item = new AsyncReply();
self.queue.add(item); self.#queue.add(item);
Codec.parse(data, 0, self, null, dataType).reply.then(function (args) { Codec.parse(data, 0, self, null, dataType).reply.then(function (args) {
item.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Propery, args, index)); item.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Propery, args, index));
}).error(function (ex) { }).error(function (ex) {
self.queue.remove(item); self.#queue.remove(item);
console.log("Esiur Property Error", ex); console.log("Esiur Property Error", ex);
}); });
}); });
@ -1874,14 +1886,14 @@ export default class DistributedConnection extends IStore {
// push to the queue to guarantee serialization // push to the queue to guarantee serialization
var item = new AsyncReply(); var item = new AsyncReply();
self.queue.add(item); self.#queue.add(item);
// Codec.parseVarArray(content, 0, content.length, self).then(function (args) { // Codec.parseVarArray(content, 0, content.length, self).then(function (args) {
Codec.parse(data, 0, self, null, dataType).reply.then(function (args) { Codec.parse(data, 0, self, null, dataType).reply.then(function (args) {
item.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Event, args, index)); item.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Event, args, index));
}).error(function (ex) { }).error(function (ex) {
self.queue.remove(item); self.#queue.remove(item);
console.log("Esiur Event Error", ex); console.log("Esiur Event Error", ex);
}); });
}); });
@ -1927,19 +1939,19 @@ export default class DistributedConnection extends IStore {
} }
#sendReply(action, callbackId) { #sendReply(action, callbackId) {
return this.this.#sendParams().addUint8(0x80 | action).addUint32(callbackId); return this.#sendParams().addUint8(0x80 | action).addUint32(callbackId);
} }
#sendEvent(evt) { #sendEvent(evt) {
return this.this.#sendParams().addUint8(evt); return this.#sendParams().addUint8(evt);
} }
#sendListenRequest(instanceId, index) _sendListenRequest(instanceId, index)
{ {
var reply = new AsyncReply(); var reply = new AsyncReply();
let callbackId = ++this.#callbackCounter; let callbackId = ++this.#callbackCounter;
this.this.#sendParams() this.#sendParams()
.addUint8(0x40 | IIPPacketAction.Listen) .addUint8(0x40 | IIPPacketAction.Listen)
.addUint32(callbackId) .addUint32(callbackId)
.addUint32(instanceId) .addUint32(instanceId)
@ -1951,12 +1963,12 @@ export default class DistributedConnection extends IStore {
return reply; return reply;
} }
#sendUnlistenRequest(instanceId, index) _sendUnlistenRequest(instanceId, index)
{ {
var reply = new AsyncReply(); var reply = new AsyncReply();
let callbackId = ++this.#callbackCounter; let callbackId = ++this.#callbackCounter;
this.this.#sendParams() this.#sendParams()
.addUint8(0x40 | IIPPacketAction.Unlisten) .addUint8(0x40 | IIPPacketAction.Unlisten)
.addUint32(callbackId) .addUint32(callbackId)
.addUint32(instanceId) .addUint32(instanceId)
@ -1970,14 +1982,14 @@ export default class DistributedConnection extends IStore {
IIPRequestAttachResource(callback, resourceId) { IIPRequestAttachResource(callback, resourceId) {
//var sl = this.this.#sendParams(); //var sl = this.#sendParams();
var self = this; var self = this;
Warehouse.getById(resourceId).then(function (r) { Warehouse.getById(resourceId).then(function (r) {
if (r != null) { if (r != null) {
if (r.instance.applicable(self.session, ActionType.Attach, null) == Ruling.Denied) { if (r.instance.applicable(self.#session, ActionType.Attach, null) == Ruling.Denied) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AttachDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AttachDenied);
return; return;
} }
@ -2085,7 +2097,7 @@ export default class DistributedConnection extends IStore {
} }
// check security // check security
if (store.instance.applicable(self.session, ActionType.CreateResource, null) != Ruling.Allowed) { if (store.instance.applicable(self.#session, ActionType.CreateResource, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.CreateDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.CreateDenied);
return; return;
} }
@ -2095,7 +2107,7 @@ export default class DistributedConnection extends IStore {
// check security // check security
if (parent != null) if (parent != null)
if (parent.instance.applicable(self.session, ActionType.AddChild, null) != Ruling.Allowed) { if (parent.instance.applicable(self.#session, ActionType.AddChild, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied);
return; return;
} }
@ -2396,7 +2408,7 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (r.instance.applicable(self.session, ActionType.Execute, ft) == Ruling.Denied) { if (r.instance.applicable(self.#session, ActionType.Execute, ft) == Ruling.Denied) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.InvokeDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.InvokeDenied);
return; return;
} }
@ -2655,12 +2667,11 @@ export default class DistributedConnection extends IStore {
self.#sendReply(IIPPacketAction.SetProperty, callback) self.#sendReply(IIPPacketAction.SetProperty, callback)
.done(); .done();
}).error(function (x) { }).error(function (x) {
self.#sendError(x.type, callback, x.code, x.message) self.#sendError(x.type, callback, x.code, x.message);
.done();
}); });
} }
else { else {
if (r.instance.applicable(self.session, ActionType.SetProperty, pt) == Ruling.Denied) { if (r.instance.applicable(self.#session, ActionType.SetProperty, pt) == Ruling.Denied) {
self.#sendError(AsyncReply.ErrorType.Exception, callback, ExceptionCode.SetPropertyDenied); self.#sendError(AsyncReply.ErrorType.Exception, callback, ExceptionCode.SetPropertyDenied);
return; return;
} }
@ -2673,7 +2684,7 @@ export default class DistributedConnection extends IStore {
self.#sendReply(IIPPacketAction.SetProperty, callback).done(); self.#sendReply(IIPPacketAction.SetProperty, callback).done();
} }
catch (ex) { catch (ex) {
self.#sendError(AsyncReply.ErrorType.Exception, callback, 0, ex.toString()).done(); self.#sendError(AsyncReply.ErrorType.Exception, callback, 0, ex.toString());
} }
} }
@ -2681,12 +2692,12 @@ export default class DistributedConnection extends IStore {
} }
else { else {
// property not found // property not found
self.#sendError(AsyncReply.ErrorType.Management, callback, ExceptionCode.PropertyNotFound).done(); self.#sendError(AsyncReply.ErrorType.Management, callback, ExceptionCode.PropertyNotFound);
} }
} }
else { else {
// resource not found // resource not found
self.#sendError(AsyncReply.ErrorType.Management, callback, ExceptionCode.PropertyNotFound).done(); self.#sendError(AsyncReply.ErrorType.Management, callback, ExceptionCode.PropertyNotFound);
} }
}); });
} }
@ -2714,7 +2725,7 @@ export default class DistributedConnection extends IStore {
self.#sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); self.#sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound);
else else
{ {
var list = resources.filter(function (r) { return r.instance.applicable(self.session, ActionType.Attach, null) != Ruling.Denied }); var list = resources.filter(function (r) { return r.instance.applicable(self.#session, ActionType.Attach, null) != Ruling.Denied });
if (list.length == 0) if (list.length == 0)
self.#sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); self.#sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound);
@ -3148,12 +3159,12 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (parent.instance.applicable(self.session, ActionType.AddChild, null) != Ruling.Allowed) { if (parent.instance.applicable(self.#session, ActionType.AddChild, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied);
return; return;
} }
if (child.instance.applicable(self.session, ActionType.AddParent, null) != Ruling.Allowed) { if (child.instance.applicable(self.#session, ActionType.AddParent, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AddParentDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AddParentDenied);
return; return;
} }
@ -3183,12 +3194,12 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (parent.instance.applicable(self.session, ActionType.RemoveChild, null) != Ruling.Allowed) { if (parent.instance.applicable(self.#session, ActionType.RemoveChild, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AddChildDenied);
return; return;
} }
if (child.instance.applicable(self.session, ActionType.RemoveParent, null) != Ruling.Allowed) { if (child.instance.applicable(self.#session, ActionType.RemoveParent, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.AddParentDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.AddParentDenied);
return; return;
} }
@ -3211,7 +3222,7 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (resource.instance.applicable(self.session, ActionType.Rename, null) != Ruling.Allowed) { if (resource.instance.applicable(self.#session, ActionType.Rename, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.RenameDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.RenameDenied);
return; return;
} }
@ -3262,7 +3273,7 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (r.instance.store.instance.applicable(self.session, ActionType.UpdateAttributes, null) != Ruling.Allowed) { if (r.instance.store.instance.applicable(self.#session, ActionType.UpdateAttributes, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.UpdateAttributeDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.UpdateAttributeDenied);
return; return;
} }
@ -3290,7 +3301,7 @@ export default class DistributedConnection extends IStore {
return; return;
} }
if (r.instance.store.instance.applicable(self.session, ActionType.UpdateAttributes, null) != Ruling.Allowed) { if (r.instance.store.instance.applicable(self.#session, ActionType.UpdateAttributes, null) != Ruling.Allowed) {
self.#sendError(ErrorType.Management, callback, ExceptionCode.UpdateAttributeDenied); self.#sendError(ErrorType.Management, callback, ExceptionCode.UpdateAttributeDenied);
return; return;
} }
@ -3476,7 +3487,7 @@ export default class DistributedConnection extends IStore {
.done() .done()
.then(x => .then(x =>
{ {
self.jitter = x[1]; self.#jitter = x[1];
self.#keepAliveTimer = setTimeout(() => self.#keepAliveTimerElapsed(), self.keepAliveInterval * 1000); self.#keepAliveTimer = setTimeout(() => self.#keepAliveTimerElapsed(), self.keepAliveInterval * 1000);
//console.log("Keep Alive Received " + self.jitter); //console.log("Keep Alive Received " + self.jitter);
@ -3489,7 +3500,7 @@ export default class DistributedConnection extends IStore {
if (r == null) { if (r == null) {
let id = self.#attachedResources.keys[i]; let id = self.#attachedResources.keys[i];
// send detach // send detach
self.#sendDetachRequest(id); self._sendDetachRequest(id);
toBeRemoved.push(id); toBeRemoved.push(id);
} }
} }
@ -3520,7 +3531,7 @@ export default class DistributedConnection extends IStore {
this.#requests.add(c, reply); this.#requests.add(c, reply);
this.this.#sendParams() this.#sendParams()
.addUint8(0x40 | IIPPacketAction.StaticCall) .addUint8(0x40 | IIPPacketAction.StaticCall)
.addUint32(c) .addUint32(c)
.addGuid(classId) .addGuid(classId)
@ -3577,7 +3588,7 @@ export default class DistributedConnection extends IStore {
jitter = Math.abs(diff - interval); jitter = Math.abs(diff - interval);
} }
this.this.#sendParams() this.#sendParams()
.addUint8(0x80 | IIPPacketAction.KeepAlive) .addUint8(0x80 | IIPPacketAction.KeepAlive)
.addUint32(callbackId) .addUint32(callbackId)
.addDateTime(now) .addDateTime(now)

View File

@ -45,7 +45,7 @@ export default class DistributedResource extends IResource
{ {
this._p.destroyed = true; this._p.destroyed = true;
this._p.attached = false; this._p.attached = false;
this._p.connection.detachResource(this._p.instanceId); this._p.connection._sendDetachRequest(this._p.instanceId);
this._emit("destroy", this); this._emit("destroy", this);
} }
@ -297,18 +297,15 @@ export default class DistributedResource extends IResource
if (this._p.properties[index] == value) if (this._p.properties[index] == value)
return null; return null;
var reply = new AsyncReply(); let reply = new AsyncReply();
var parameters = Codec.compose(value, this._p.connection); let self = this;
var self = this;
this._p.connection._sendRequest(IIPPacketAction.SetProperty) this._p.connection._sendSetProperty(self._p.instanceId, index, value)
.addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters)
.done()
.then(function(res) .then(function(res)
{ {
// not really needed, server will always send property modified, this only happens if the programmer forgot to emit in property setter // not really needed, server will always send property modified, this only happens if the programmer forgot to emit in property setter
self._p.properties[index] = value; //self._p.properties[index] = value;
reply.trigger(null); reply.trigger(null);
}); });

View File

@ -27,9 +27,10 @@
"use strict"; "use strict";
import AuthenticationMethod from "../../Security/Authority/AuthenticationMethod.js";
import IIPAuthPacketCommand from "./IIPAuthPacketCommand.js"; import IIPAuthPacketCommand from "./IIPAuthPacketCommand.js";
import IIPAuthPacketAction from "./IIPAuthPacketAction.js"; import IIPAuthPacketAction from "./IIPAuthPacketAction.js";
import AuthenticationMethod from "../../Security/Authority/AuthenticationMethod.js"; import IIPAuthPacketEvent from "./IIPAuthPacketEvent.js";
import TransmissionType from '../../Data/TransmissionType.js'; import TransmissionType from '../../Data/TransmissionType.js';
export default class IIPAuthPacket export default class IIPAuthPacket
@ -117,7 +118,7 @@ export default class IIPAuthPacket
this.dataType = parsed.type; this.dataType = parsed.type;
offset += parsed.size; offset += parsed.size;
} else if (command == IIPAuthPacketCommand.Action) { } else if (this.command == IIPAuthPacketCommand.Action) {
this.action = (data[offset++]); this.action = (data[offset++]);
@ -140,7 +141,7 @@ export default class IIPAuthPacket
this.challenge = data.clip(offset, hashLength); this.challenge = data.clip(offset, hashLength);
offset += hashLength; offset += hashLength;
} else if (action == IIPAuthPacketAction.AuthenticatePrivateHashCert || } else if (this.action == IIPAuthPacketAction.AuthenticatePrivateHashCert ||
this.action == IIPAuthPacketAction.AuthenticatePublicPrivateHashCert) { this.action == IIPAuthPacketAction.AuthenticatePublicPrivateHashCert) {
if (this.#notEnough(offset, ends, 3)) if (this.#notEnough(offset, ends, 3))
@ -170,7 +171,7 @@ export default class IIPAuthPacket
offset += certLength; offset += certLength;
} else if (action == IIPAuthPacketAction.IAuthPlain) { } else if (this.action == IIPAuthPacketAction.IAuthPlain) {
if (this.#notEnough(offset, ends, 5)) if (this.#notEnough(offset, ends, 5))
return -this.#dataLengthNeeded; return -this.#dataLengthNeeded;
@ -186,7 +187,7 @@ export default class IIPAuthPacket
this.dataType = parsed.type; this.dataType = parsed.type;
offset += parsed.size; offset += parsed.size;
} else if (action == IIPAuthPacketAction.IAuthHashed) { } else if (this.action == IIPAuthPacketAction.IAuthHashed) {
if (this.#notEnough(offset, ends, 7)) if (this.#notEnough(offset, ends, 7))
return -this.#dataLengthNeeded; return -this.#dataLengthNeeded;
@ -206,7 +207,7 @@ export default class IIPAuthPacket
offset += cl; offset += cl;
} else if (action == IIPAuthPacketAction.IAuthEncrypted) { } else if (this.action == IIPAuthPacketAction.IAuthEncrypted) {
if (this.#notEnough(offset, ends, 7)) if (this.#notEnough(offset, ends, 7))
return -this.#dataLengthNeeded; return -this.#dataLengthNeeded;
@ -226,9 +227,9 @@ export default class IIPAuthPacket
offset += cl; offset += cl;
} else if (action == IIPAuthPacketAction.EstablishNewSession) { } else if (this.action == IIPAuthPacketAction.EstablishNewSession) {
// Nothing here // Nothing here
} else if (action == IIPAuthPacketAction.EstablishResumeSession) { } else if (this.action == IIPAuthPacketAction.EstablishResumeSession) {
if (this.#notEnough(offset, ends, 1)) if (this.#notEnough(offset, ends, 1))
return -this.#dataLengthNeeded; return -this.#dataLengthNeeded;
@ -242,7 +243,7 @@ export default class IIPAuthPacket
offset += sessionLength; offset += sessionLength;
} else if (action == IIPAuthPacketAction.EncryptKeyExchange) { } else if (this.action == IIPAuthPacketAction.EncryptKeyExchange) {
if (this.#notEnough(offset, ends, 2)) if (this.#notEnough(offset, ends, 2))
return -this.#dataLengthNeeded; return -this.#dataLengthNeeded;
@ -258,7 +259,7 @@ export default class IIPAuthPacket
offset += keyLength; offset += keyLength;
} else if (action == IIPAuthPacketAction.RegisterEndToEndKey || } else if (this.action == IIPAuthPacketAction.RegisterEndToEndKey ||
this.action == IIPAuthPacketAction.RegisterHomomorphic) { this.action == IIPAuthPacketAction.RegisterHomomorphic) {
if (this.#notEnough(offset, ends, 3)) if (this.#notEnough(offset, ends, 3))
@ -278,7 +279,7 @@ export default class IIPAuthPacket
offset += keyLength; offset += keyLength;
} }
} else if (command == IIPAuthPacketCommand.Event) { } else if (this.command == IIPAuthPacketCommand.Event) {
this.event = data[offset++]; this.event = data[offset++];

View File

@ -1,11 +1,16 @@
import { UInt8 } from "../../Data/ExtendedTypes.js";
// IIPAuthPacketIAuthHeader // IIPAuthPacketIAuthHeader
export default export default
{ {
Reference: 0, Reference: new UInt8(0),
Destination: 1, Destination: new UInt8(1),
Clue: 2, Clue: new UInt8(2),
RequiredFormat: 3, RequiredFormat: new UInt8(3),
ContentFormat: 4, ContentFormat: new UInt8(4),
Content: 5, Content: new UInt8(5),
Timeout: 6 Trials: new UInt8(6),
Issue: new UInt8(7),
Expire: new UInt8(8)
} }

View File

@ -0,0 +1,52 @@
//AuthorizationResults
import IIPAuthPacketIAuthHeader from '../../Net/Packets/IIPAuthPacketIAuthHeader.js';
export default class AuthorizationRequest {
reference;
destination;
clue;
requiredFormat;
contentFormat;
content;
trials;
issue = new Date();
expire;
get expired (){
return new Date() > this.expire;
}
get timeout() {
if (this.expire != null)
return (this.expire - new Date()) / 1000;
else
return 30;
}
constructor(headers){
this.reference = headers.get(IIPAuthPacketIAuthHeader.Reference);
this.destination = headers.get(IIPAuthPacketIAuthHeader.Destination);
this.clue = headers.get(IIPAuthPacketIAuthHeader.Clue);
if (headers.has(IIPAuthPacketIAuthHeader.RequiredFormat))
requiredFormat = headers.get(IIPAuthPacketIAuthHeader.RequiredFormat);
if (headers.has(IIPAuthPacketIAuthHeader.ContentFormat))
contentFormat = headers.get(IIPAuthPacketIAuthHeader.ContentFormat);
if (headers.has(IIPAuthPacketIAuthHeader.Content))
content = headers.get(IIPAuthPacketIAuthHeader.Content);
if (headers.has(IIPAuthPacketIAuthHeader.Trials))
trials = headers.get(IIPAuthPacketIAuthHeader.Trials);
if (headers.has(IIPAuthPacketIAuthHeader.Issue))
this.issue = headers.get(IIPAuthPacketIAuthHeader.Issue);
if (headers.has(IIPAuthPacketIAuthHeader.Expire))
expire = headers.get(IIPAuthPacketIAuthHeader.Expire);
}
}

View File

@ -1,19 +1,33 @@
//AuthorizationResults //AuthorizationResults
export default class { import AuthorizationResultsResponse from './AuthorizationResultsResponse.js';
response;
destination;
requiredFormat;
clue;
timeout; // 0 means no timeout export default class AuthorizationResults {
response = AuthorizationResultsResponse.Failed;
reference; reference;
destination;
clue;
requiredFormat;
contentFormat;
content;
trials;
issue = new Date(); issue = new Date();
expire;
get expired (){ get expired (){
this.timeout == 0 ? false : ((new Date() - this.issue) / 1000) > this.timeout; return new Date() > this.expire;
}
get timeout() {
if (this.expire != null)
return (this.expire - new Date()) / 1000;
else
return 30;
}
constructor(response = AuthorizationResultsResponse.Failed){
this.response = response;
} }
} }

View File

@ -0,0 +1,10 @@
// AuthorizationResultsResponse
export default {
Success: 0,
Failed: 1,
Expired: 2,
ServiceUnavailable: 3,
IAuthPlain: 4,
IAuthHashed: 5,
IAuthEncrypted: 6
}

View File

@ -1,5 +1,6 @@
import AsyncReply from "../../Core/AsyncReply.js"; import AsyncReply from "../../Core/AsyncReply.js";
import IResource from "../../Resource/IResource.js"; import IResource from "../../Resource/IResource.js";
import AuthorizationResults from '../../Security/Membership/AuthorizationResults.js';
export default class IMembership extends IResource export default class IMembership extends IResource
{ {