| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-09-25 17:05:54 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-09-25 17:10:23 UTC |
| parent | 4b165cb856c5236eec193d49e302934e837d91c2 |
| xmpp/Client.hx | +12 | -2 |
| xmpp/JID.hx | +4 | -0 |
| xmpp/Persistence.hx | +2 | -0 |
| xmpp/persistence/browser.js | +32 | -1 |
| xmpp/streams/XmppJsStream.hx | +6 | -2 |
diff --git a/xmpp/Client.hx b/xmpp/Client.hx index a271840..cd4eeca 100644 --- a/xmpp/Client.hx +++ b/xmpp/Client.hx @@ -31,11 +31,17 @@ class Client extends xmpp.EventEmitter { this.persistence = persistence; stream = new Stream(); stream.on("status/online", this.onConnected); - stream.on("auth/password-needed", (data)->this.trigger("auth/password-needed", { jid: this.jid })); } public function start() { - stream.connect(jid); + persistence.getLogin(jid, (login) -> { + if (login.token == null) { + stream.on("auth/password-needed", (data)->this.trigger("auth/password-needed", { jid: this.jid })); + } else { + stream.on("auth/password-needed", (data)->this.stream.trigger("auth/password", { password: login.token })); + } + stream.connect(login.clientId == null ? jid : jid + "/" + login.clientId); + }); } public function addChatMessageListener(handler:ChatMessage->Void):Void { @@ -43,6 +49,10 @@ class Client extends xmpp.EventEmitter { } private function onConnected(data) { + if (data != null && data.jid != null) { + final jidp = JID.parse(data.jid); + if (!jidp.isBare()) persistence.storeLogin(jidp.asBare().asString(), jidp.resource, null); + } this.stream.on("message", function(event) { final stanza:Stanza = event.stanza; final chatMessage = ChatMessage.fromStanza(stanza, jid); diff --git a/xmpp/JID.hx b/xmpp/JID.hx index a4bd3a5..cedb018 100644 --- a/xmpp/JID.hx +++ b/xmpp/JID.hx @@ -62,6 +62,10 @@ class JID { return node == null; } + public function isBare():Bool { + return resource == null; + } + public function equals(rhs:JID):Bool { return ( this.node == rhs.node && diff --git a/xmpp/Persistence.hx b/xmpp/Persistence.hx index 39b2cbe..80bc318 100644 --- a/xmpp/Persistence.hx +++ b/xmpp/Persistence.hx @@ -11,4 +11,6 @@ abstract class Persistence { abstract public function storeMedia(mime:String, bytes:BytesData, callback: ()->Void):Void; abstract public function storeCaps(caps:Caps):Void; abstract public function getCaps(ver:String, callback: (Caps)->Void):Void; + abstract public function storeLogin(login:String, clientId:String, token:Null<String>):Void; + abstract public function getLogin(login:String, callback:({ ?clientId: String, ?token: String })->Void):Void; } diff --git a/xmpp/persistence/browser.js b/xmpp/persistence/browser.js index 9a32d34..8522fe9 100644 --- a/xmpp/persistence/browser.js +++ b/xmpp/persistence/browser.js @@ -4,13 +4,14 @@ exports.xmpp.persistence = { browser: (dbname) => { var db = null; - var dbOpenReq = indexedDB.open(dbname, 1); + var dbOpenReq = indexedDB.open(dbname); dbOpenReq.onerror = console.error; dbOpenReq.onupgradeneeded = (event) => { const upgradeDb = event.target.result; const store = upgradeDb.createObjectStore("messages", { keyPath: "serverId" }); store.createIndex("account", ["account", "timestamp"]); store.createIndex("conversation", ["account", "conversation", "timestamp"]); + upgradeDb.createObjectStore("keyvaluepairs"); }; dbOpenReq.onsuccess = (event) => { db = event.target.result; @@ -24,6 +25,13 @@ exports.xmpp.persistence = { return "/.well-known/ni/" + hashAlgorithm + "/" + b64url; } + function promisifyRequest(request) { + return new Promise((resolve, reject) => { + request.oncomplete = request.onsuccess = () => resolve(request.result); + request.onabort = request.onerror = () => reject(request.error); + }); + } + return { lastId: function(account, jid, callback) { const tx = db.transaction(["messages"], "readonly"); @@ -146,6 +154,29 @@ exports.xmpp.persistence = { } else { callback(null); } + }, + + storeLogin: function(login, clientId, token) { + const tx = db.transaction(["keyvaluepairs"], "readwrite"); + const store = tx.objectStore("keyvaluepairs"); + store.put(clientId, "login:clientId:" + login).onerror = console.error; + if (token != null) store.put(token, "login:token:" + login).onerror = console.error; + }, + + getLogin: function(login, callback) { + const tx = db.transaction(["keyvaluepairs"], "readonly"); + const store = tx.objectStore("keyvaluepairs"); + Promise.all([ + promisifyRequest(store.get("login:clientId:" + login)), + promisifyRequest(store.get("login:token:" + login)) + ]).then((result) => { + callback({ + clientId: result[0], + token: result[1] + }); + }).catch((e) => { + callback({}); + }); } } } diff --git a/xmpp/streams/XmppJsStream.hx b/xmpp/streams/XmppJsStream.hx index 570afdb..1eb5a76 100644 --- a/xmpp/streams/XmppJsStream.hx +++ b/xmpp/streams/XmppJsStream.hx @@ -19,6 +19,7 @@ extern class XmppJsClient { @:jsRequire("@xmpp/jid", "JID") extern class XmppJsJID { function new(jid:String); + function toString():String; var local(default, set):String; var domain(default, set):String; @@ -49,6 +50,7 @@ extern class XmppJsLtx { static function isNode(el:Dynamic):Bool; static function isElement(el:Dynamic):Bool; static function isText(el:Dynamic):Bool; + static function parse(input:String):XmppJsXml; } @:jsRequire("@xmpp/id") @@ -124,6 +126,7 @@ class XmppJsStream extends GenericStream { service: connectionURI, domain: jid.domain, username: jid.local, + resource: jid.resource, password: event.password, }); @@ -133,7 +136,8 @@ class XmppJsStream extends GenericStream { this.client = xmpp; - xmpp.on("online", function (data) { + xmpp.on("online", function (jid) { + this.jid = jid; this.state.event("connection-success"); }); @@ -196,7 +200,7 @@ class XmppJsStream extends GenericStream { /* State handlers */ private function onOnline(event) { - trigger("status/online", {}); + trigger("status/online", { jid: jid.toString() }); } private function onOffline(event) {