Skip to content

Commit 94b70b5

Browse files
committed
signature.test.ts
1 parent 6c8461c commit 94b70b5

9 files changed

Lines changed: 189 additions & 81 deletions

File tree

dist/solid-ui.js

Lines changed: 120 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,7 +2655,7 @@ var ChatChannel = /*#__PURE__*/function () {
26552655
var oldMsg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
26562656
var deleteIt = arguments.length > 2 ? arguments[2] : undefined;
26572657
return /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
2658-
var sts, now, timestamp, dateStamp, chatDocument, message, me, msg, privateKey, errMsg;
2658+
var sts, now, timestamp, dateStamp, chatDocument, message, me, msg, oldMsgMaker, errMsg, privateKey, _errMsg;
26592659
return _regenerator["default"].wrap(function _callee2$(_context2) {
26602660
while (1) switch (_context2.prev = _context2.next) {
26612661
case 0:
@@ -2668,55 +2668,73 @@ var ChatChannel = /*#__PURE__*/function () {
26682668
me = _solidLogic.authn.currentUser(); // If already logged on
26692669
msg = _signature.getBlankMsg;
26702670
msg.id = message;
2671-
if (oldMsg) {
2672-
// edit message replaces old one
2673-
sts.push($rdf.st(mostRecentVersion(oldMsg), ns.dct('isReplacedBy'), message, chatDocument));
2674-
// do we need to rebuild oldMsg signaturen ?
2675-
if (deleteIt) {
2676-
sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument));
2677-
msg.dateDeleted = dateStamp;
2678-
}
2679-
} else {
2680-
// link new message to channel
2681-
sts.push($rdf.st(_this.channel, ns.wf('message'), message, chatDocument));
2671+
if (!oldMsg) {
2672+
_context2.next = 22;
2673+
break;
2674+
}
2675+
// edit message replaces old one
2676+
oldMsgMaker = _solidLogic.store.any(oldMsg, ns.foaf('maker')); // may not be needed here, but needed on READ
2677+
if (!(oldMsgMaker.uri === me.uri)) {
2678+
_context2.next = 16;
2679+
break;
2680+
}
2681+
sts.push($rdf.st(mostRecentVersion(oldMsg), ns.dct('isReplacedBy'), message, chatDocument));
2682+
if (deleteIt) {
2683+
// we need to add a specific signature, else anyone can delete a msg ?
2684+
sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument));
2685+
msg.dateDeleted = dateStamp;
26822686
}
2687+
_context2.next = 20;
2688+
break;
2689+
case 16:
2690+
errMsg = 'Error you cannot delete/edit a message from someone else : \n' + oldMsgMaker.uri;
2691+
debug.warn(errMsg);
2692+
alert(errMsg);
2693+
throw new Error(errMsg);
2694+
case 20:
2695+
_context2.next = 23;
2696+
break;
2697+
case 22:
2698+
// link new message to channel
2699+
sts.push($rdf.st(_this.channel, ns.wf('message'), message, chatDocument));
2700+
case 23:
26832701
sts.push($rdf.st(message, ns.sioc('content'), _solidLogic.store.literal(text), chatDocument));
26842702
msg.content = text;
26852703
sts.push($rdf.st(message, ns.dct('created'), dateStamp, chatDocument));
26862704
msg.created = dateStamp;
26872705
if (!me) {
2688-
_context2.next = 21;
2706+
_context2.next = 34;
26892707
break;
26902708
}
26912709
sts.push($rdf.st(message, ns.foaf('maker'), me, chatDocument));
26922710
msg.maker = me;
26932711
// privateKey the cached private key of me, cache should be deleted after a certain time
2694-
_context2.next = 19;
2712+
_context2.next = 32;
26952713
return (0, _keys.getPrivateKey)(me);
2696-
case 19:
2714+
case 32:
26972715
privateKey = _context2.sent;
26982716
sts.push($rdf.st(message, $rdf.sym("".concat(_signature.SEC, "Proof")), $rdf.sym((0, _signature.signMsg)(msg, privateKey), chatDocument)));
2699-
case 21:
2700-
_context2.prev = 21;
2701-
_context2.next = 24;
2717+
case 34:
2718+
_context2.prev = 34;
2719+
_context2.next = 37;
27022720
return _solidLogic.store.updater.update([], sts);
2703-
case 24:
2704-
_context2.next = 32;
2721+
case 37:
2722+
_context2.next = 45;
27052723
break;
2706-
case 26:
2707-
_context2.prev = 26;
2708-
_context2.t0 = _context2["catch"](21);
2709-
errMsg = 'Error saving chat message: ' + _context2.t0;
2710-
debug.warn(errMsg);
2711-
alert(errMsg);
2712-
throw new Error(errMsg);
2713-
case 32:
2724+
case 39:
2725+
_context2.prev = 39;
2726+
_context2.t0 = _context2["catch"](34);
2727+
_errMsg = 'Error saving chat message: ' + _context2.t0;
2728+
debug.warn(_errMsg);
2729+
alert(_errMsg);
2730+
throw new Error(_errMsg);
2731+
case 45:
27142732
return _context2.abrupt("return", message);
2715-
case 33:
2733+
case 46:
27162734
case "end":
27172735
return _context2.stop();
27182736
}
2719-
}, _callee2, null, [[21, 26]]);
2737+
}, _callee2, null, [[34, 39]]);
27202738
})();
27212739
});
27222740
function updateMessage(_x2) {
@@ -4011,27 +4029,21 @@ exports.getPrivateKey = getPrivateKey;
40114029
exports.getPublicKey = getPublicKey;
40124030
var _regenerator = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js"));
40134031
var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ "./node_modules/@babel/runtime/helpers/asyncToGenerator.js"));
4032+
var debug = _interopRequireWildcard(__webpack_require__(/*! ../debug */ "./lib/debug.js"));
40144033
var _secp256k = __webpack_require__(/*! @noble/curves/secp256k1 */ "./node_modules/@noble/curves/secp256k1.js");
40154034
var _utils = __webpack_require__(/*! @noble/hashes/utils */ "./node_modules/@noble/hashes/utils.js");
40164035
var _signature = __webpack_require__(/*! ./signature */ "./lib/chat/signature.js");
40174036
var _solidLogic = __webpack_require__(/*! solid-logic */ "./node_modules/solid-logic/lib/index.js");
40184037
var $rdf = _interopRequireWildcard(__webpack_require__(/*! rdflib */ "./node_modules/rdflib/esm/index.js"));
40194038
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
40204039
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
4021-
// should have webcrypto.getRandomValues defined
4022-
40234040
function generatePrivateKey() {
40244041
return (0, _utils.bytesToHex)(_secp256k.schnorr.utils.randomPrivateKey());
40254042
}
40264043
function generatePublicKey(privateKey) {
40274044
return (0, _utils.bytesToHex)(_secp256k.schnorr.getPublicKey(privateKey));
40284045
}
40294046
function getPublicKey(webId) {
4030-
// find publickey
4031-
/* const url = new URL(webId)
4032-
url.hash = ''
4033-
store.fetcher.load(url.href)
4034-
let publicKey = store.any(store.sym(webId), store.sym(CERT +'publicKey')) */
40354047
var publicKey = publicKeyExists(webId);
40364048
return publicKey === null || publicKey === void 0 ? void 0 : publicKey.uri;
40374049
}
@@ -4043,28 +4055,78 @@ function publicKeyExists(webId) {
40434055
var publicKey = _solidLogic.store.any(_solidLogic.store.sym(webId), _solidLogic.store.sym(_signature.CERT + 'publicKey'));
40444056
return publicKey;
40454057
}
4046-
function privateKeyExists(webId) {
4047-
var url = new URL(webId);
4048-
var privateKeyUrl = url.hostname + '/profile/privateKey.ttl';
4049-
_solidLogic.store.fetcher.load(privateKeyUrl);
4050-
var privateKey = _solidLogic.store.any(_solidLogic.store.sym(webId), _solidLogic.store.sym(_signature.CERT + 'privateKey'));
4051-
return privateKey;
4058+
function privateKeyExists(_x) {
4059+
return _privateKeyExists.apply(this, arguments);
4060+
}
4061+
function _privateKeyExists() {
4062+
_privateKeyExists = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(webId) {
4063+
var url, privateKeyUrl, privateKey, _err$response, data, contentType, response;
4064+
return _regenerator["default"].wrap(function _callee$(_context) {
4065+
while (1) switch (_context.prev = _context.next) {
4066+
case 0:
4067+
url = new URL(webId);
4068+
privateKeyUrl = url.hostname + '/profile/privateKey.ttl';
4069+
_context.prev = 2;
4070+
_solidLogic.store.fetcher.load(privateKeyUrl);
4071+
privateKey = _solidLogic.store.any(_solidLogic.store.sym(webId), _solidLogic.store.sym(_signature.CERT + 'privateKey'));
4072+
return _context.abrupt("return", privateKey);
4073+
case 8:
4074+
_context.prev = 8;
4075+
_context.t0 = _context["catch"](2);
4076+
if (!((_context.t0 === null || _context.t0 === void 0 ? void 0 : (_err$response = _context.t0.response) === null || _err$response === void 0 ? void 0 : _err$response.status) === 404)) {
4077+
_context.next = 25;
4078+
break;
4079+
}
4080+
_context.prev = 11;
4081+
// create privateKey resource
4082+
data = '';
4083+
contentType = 'text/ttl';
4084+
_context.next = 16;
4085+
return _solidLogic.store.fetcher.webOperation('PUT', privateKeyUrl, {
4086+
data: data,
4087+
contentType: contentType
4088+
});
4089+
case 16:
4090+
response = _context.sent;
4091+
_context.next = 23;
4092+
break;
4093+
case 19:
4094+
_context.prev = 19;
4095+
_context.t1 = _context["catch"](11);
4096+
debug.log('createIfNotExists doc FAILED: ' + privateKeyUrl + ': ' + _context.t1);
4097+
throw _context.t1;
4098+
case 23:
4099+
delete _solidLogic.store.fetcher.requested[privateKeyUrl]; // delete cached 404 error
4100+
return _context.abrupt("return", undefined);
4101+
case 25:
4102+
debug.log('createIfNotExists doc FAILED: ' + privateKeyUrl + ': ' + _context.t0);
4103+
throw _context.t0;
4104+
case 27:
4105+
case "end":
4106+
return _context.stop();
4107+
}
4108+
}, _callee, null, [[2, 8], [11, 19]]);
4109+
}));
4110+
return _privateKeyExists.apply(this, arguments);
40524111
}
4053-
function getPrivateKey(_x) {
4112+
function getPrivateKey(_x2) {
40544113
return _getPrivateKey.apply(this, arguments);
40554114
}
40564115
function _getPrivateKey() {
4057-
_getPrivateKey = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(webId) {
4116+
_getPrivateKey = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(webId) {
40584117
var url, privateKeyUrl, publicKey, privateKey, del, add;
4059-
return _regenerator["default"].wrap(function _callee$(_context) {
4060-
while (1) switch (_context.prev = _context.next) {
4118+
return _regenerator["default"].wrap(function _callee2$(_context2) {
4119+
while (1) switch (_context2.prev = _context2.next) {
40614120
case 0:
40624121
url = new URL(webId);
40634122
privateKeyUrl = url.hostname + '/profile/privateKey.ttl'; // find publickey
40644123
publicKey = publicKeyExists(webId); // find privateKey
4065-
privateKey = privateKeyExists(webId); // create key pair
4124+
_context2.next = 5;
4125+
return privateKeyExists(webId);
4126+
case 5:
4127+
privateKey = _context2.sent;
40664128
if (!(!privateKey || !publicKey)) {
4067-
_context.next = 15;
4129+
_context2.next = 17;
40684130
break;
40694131
}
40704132
del = [];
@@ -4075,15 +4137,15 @@ function _getPrivateKey() {
40754137
publicKey = _solidLogic.store.sym(generatePublicKey(privateKey.uri));
40764138
add.push($rdf.st($rdf.sym(webId), $rdf.sym(_signature.CERT + 'privateKey'), $rdf.literal(privateKey.uri), $rdf.sym(privateKeyUrl)));
40774139
add.push($rdf.st($rdf.sym(webId), $rdf.sym(_signature.CERT + 'publicKey'), $rdf.literal(publicKey.uri), $rdf.sym(url.href)));
4078-
_context.next = 15;
4140+
_context2.next = 17;
40794141
return _solidLogic.store.updater.updateMany(del, add);
4080-
case 15:
4081-
return _context.abrupt("return", privateKey.uri);
4082-
case 16:
4142+
case 17:
4143+
return _context2.abrupt("return", privateKey.uri);
4144+
case 18:
40834145
case "end":
4084-
return _context.stop();
4146+
return _context2.stop();
40854147
}
4086-
}, _callee);
4148+
}, _callee2);
40874149
}));
40884150
return _getPrivateKey.apply(this, arguments);
40894151
}
@@ -5032,8 +5094,8 @@ exports.utf8Encoder = exports.utf8Decoder = void 0;
50325094
exports.validateMsg = validateMsg;
50335095
exports.verifySignature = verifySignature;
50345096
var _secp256k = __webpack_require__(/*! @noble/curves/secp256k1 */ "./node_modules/@noble/curves/secp256k1.js");
5035-
var _sha = __webpack_require__(/*! @noble/hashes/sha256 */ "./node_modules/@noble/hashes/sha256.js");
50365097
var _utils = __webpack_require__(/*! @noble/hashes/utils */ "./node_modules/@noble/hashes/utils.js");
5098+
var _sha = __webpack_require__(/*! @noble/hashes/sha256 */ "./node_modules/@noble/hashes/sha256.js");
50375099
// import {utf8Encoder} from './utils'
50385100
// import { getPublicKey } from './keys'
50395101

@@ -13176,8 +13238,8 @@ Object.defineProperty(exports, "__esModule", ({
1317613238
}));
1317713239
exports.versionInfo = void 0;
1317813240
var versionInfo = {
13179-
buildTime: '2023-04-18T15:37:08Z',
13180-
commit: '2da93f8e0bdbaf455f9d83bfc2d748e52cb24126',
13241+
buildTime: '2023-04-19T13:57:02Z',
13242+
commit: '6c8461c90348c12751456ce058874760f5b987aa',
1318113243
npmInfo: {
1318213244
'solid-ui': '2.4.27',
1318313245
npm: '8.19.4',

dist/solid-ui.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/solid-ui.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/solid-ui.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/chat/chatLogic.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,18 @@ export class ChatChannel {
5656
const msg = getBlankMsg
5757
msg.id = message
5858
if (oldMsg) { // edit message replaces old one
59-
sts.push($rdf.st(mostRecentVersion(oldMsg), ns.dct('isReplacedBy'), message, chatDocument))
60-
// do we need to rebuild oldMsg signaturen ?
61-
if (deleteIt) {
62-
sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument))
63-
msg.dateDeleted = dateStamp
59+
const oldMsgMaker = store.any(oldMsg, ns.foaf('maker')) // may not be needed here, but needed on READ
60+
if (oldMsgMaker.uri === me.uri) {
61+
sts.push($rdf.st(mostRecentVersion(oldMsg), ns.dct('isReplacedBy'), message, chatDocument))
62+
if (deleteIt) { // we need to add a specific signature, else anyone can delete a msg ?
63+
sts.push($rdf.st(message, ns.schema('dateDeleted'), dateStamp, chatDocument))
64+
msg.dateDeleted = dateStamp
65+
}
66+
} else {
67+
const errMsg = 'Error you cannot delete/edit a message from someone else : \n' + oldMsgMaker.uri
68+
debug.warn(errMsg)
69+
alert(errMsg)
70+
throw new Error(errMsg)
6471
}
6572
} else { // link new message to channel
6673
sts.push($rdf.st(this.channel, ns.wf('message'), message, chatDocument))

src/chat/keys.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import * as debug from '../debug'
12
import { schnorr } from '@noble/curves/secp256k1'
23
import { bytesToHex } from '@noble/hashes/utils'
34
import { CERT } from './signature'
45
import { store } from 'solid-logic'
56
import * as $rdf from 'rdflib'
67
import { NamedNode, literal } from 'rdflib'
7-
import crypto from 'crypto' // should have webcrypto.getRandomValues defined
88

99
export function generatePrivateKey (): string {
1010
return bytesToHex(schnorr.utils.randomPrivateKey())
@@ -15,11 +15,6 @@ export function generatePublicKey (privateKey: string): string {
1515
}
1616

1717
export function getPublicKey (webId) {
18-
// find publickey
19-
/* const url = new URL(webId)
20-
url.hash = ''
21-
store.fetcher.load(url.href)
22-
let publicKey = store.any(store.sym(webId), store.sym(CERT +'publicKey')) */
2318
const publicKey = publicKeyExists(webId)
2419
return publicKey?.uri as any
2520
}
@@ -33,21 +28,43 @@ function publicKeyExists (webId: string): NamedNode {
3328
return publicKey as NamedNode
3429
}
3530

36-
function privateKeyExists (webId: string): NamedNode {
31+
async function privateKeyExists (webId: string) {
3732
const url = new URL(webId)
3833
const privateKeyUrl = url.hostname + '/profile/privateKey.ttl'
39-
store.fetcher.load(privateKeyUrl)
40-
const privateKey = store.any(store.sym(webId), store.sym(CERT + 'privateKey'))
41-
return privateKey as NamedNode
34+
try {
35+
store.fetcher.load(privateKeyUrl)
36+
const privateKey = store.any(store.sym(webId), store.sym(CERT + 'privateKey'))
37+
return privateKey as NamedNode
38+
} catch (err) {
39+
if (err?.response?.status === 404) {
40+
try {
41+
// create privateKey resource
42+
const data = ''
43+
const contentType = 'text/ttl'
44+
const response = await store.fetcher.webOperation('PUT', privateKeyUrl, {
45+
data,
46+
contentType
47+
})
48+
// create ACL resource
49+
} catch (err) {
50+
debug.log('createIfNotExists doc FAILED: ' + privateKeyUrl + ': ' + err)
51+
throw err
52+
}
53+
delete store.fetcher.requested[privateKeyUrl] // delete cached 404 error
54+
return undefined
55+
}
56+
debug.log('createIfNotExists doc FAILED: ' + privateKeyUrl + ': ' + err)
57+
throw err
58+
}
4259
}
4360

44-
export async function getPrivateKey (webId) {
61+
export async function getPrivateKey (webId: string) {
4562
const url = new URL(webId)
4663
const privateKeyUrl = url.hostname + '/profile/privateKey.ttl'
4764
// find publickey
4865
let publicKey = publicKeyExists(webId)
4966
// find privateKey
50-
let privateKey = privateKeyExists(webId)
67+
let privateKey = await privateKeyExists(webId)
5168
// create key pair
5269
if (!privateKey || !publicKey) {
5370
const del: any[] = []
@@ -62,5 +79,5 @@ export async function getPrivateKey (webId) {
6279
add.push($rdf.st($rdf.sym(webId), $rdf.sym(CERT + 'publicKey'), $rdf.literal(publicKey.uri), $rdf.sym(url.href)))
6380
await store.updater.updateMany(del, add)
6481
}
65-
return privateKey.uri as any
82+
return privateKey.uri as string
6683
}

src/chat/signature.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { schnorr } from '@noble/curves/secp256k1'
2-
import { sha256 } from '@noble/hashes/sha256'
32
import { bytesToHex } from '@noble/hashes/utils'
3+
import { sha256 } from '@noble/hashes/sha256'
44

55
// import {utf8Encoder} from './utils'
66
// import { getPublicKey } from './keys'
@@ -82,7 +82,7 @@ export function serializeMsg (msg: UnsignedMsg): string {
8282
return JSON.stringify(msg)
8383
}
8484

85-
export function getMsgHash (message: UnsignedMsg): string {
85+
export function getMsgHash (message: UnsignedMsg) {
8686
const msgHash = sha256(utf8Encoder.encode(serializeMsg(message)))
8787
return bytesToHex(msgHash)
8888
}

0 commit comments

Comments
 (0)