@ztimson/momentum 0.52.0 → 0.52.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.d.ts +46 -4
- package/dist/actions.d.ts.map +1 -1
- package/dist/ai.d.ts +20 -2
- package/dist/ai.d.ts.map +1 -1
- package/dist/analytics.d.ts +54 -24
- package/dist/analytics.d.ts.map +1 -1
- package/dist/api.d.ts +31 -8
- package/dist/api.d.ts.map +1 -1
- package/dist/auth.d.ts +103 -4
- package/dist/auth.d.ts.map +1 -1
- package/dist/client.d.ts +24 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/core.d.ts +16 -3
- package/dist/core.d.ts.map +1 -1
- package/dist/data.d.ts +13 -7
- package/dist/data.d.ts.map +1 -1
- package/dist/email.d.ts +16 -5
- package/dist/email.d.ts.map +1 -1
- package/dist/index.cjs +346 -178
- package/dist/index.mjs +346 -178
- package/dist/momentum.d.ts +2 -6
- package/dist/momentum.d.ts.map +1 -1
- package/dist/payments.d.ts +65 -4
- package/dist/payments.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -285,7 +285,7 @@ class Cache {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
function blackOrWhite(background) {
|
|
288
|
-
const exploded = background.match(background.length >= 6 ? /\w\w/g : /\w/g);
|
|
288
|
+
const exploded = background == null ? void 0 : background.match(background.length >= 6 ? /\w\w/g : /\w/g);
|
|
289
289
|
if (!exploded) return "black";
|
|
290
290
|
const [r2, g, b2] = exploded.map((hex) => parseInt(hex, 16));
|
|
291
291
|
const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b2) / 255;
|
|
@@ -663,31 +663,13 @@ __publicField2(_Http, "interceptors", {});
|
|
|
663
663
|
__publicField2(_Http, "headers", {});
|
|
664
664
|
let Http = _Http;
|
|
665
665
|
const CliEffects = {
|
|
666
|
-
CLEAR: "\x1B[0m"
|
|
667
|
-
BRIGHT: "\x1B[1m",
|
|
668
|
-
DIM: "\x1B[2m",
|
|
669
|
-
UNDERSCORE: "\x1B[4m",
|
|
670
|
-
BLINK: "\x1B[5m",
|
|
671
|
-
REVERSE: "\x1B[7m",
|
|
672
|
-
HIDDEN: "\x1B[8m"
|
|
666
|
+
CLEAR: "\x1B[0m"
|
|
673
667
|
};
|
|
674
668
|
const CliForeground = {
|
|
675
|
-
BLACK: "\x1B[30m",
|
|
676
669
|
RED: "\x1B[31m",
|
|
677
|
-
GREEN: "\x1B[32m",
|
|
678
670
|
YELLOW: "\x1B[33m",
|
|
679
671
|
BLUE: "\x1B[34m",
|
|
680
|
-
|
|
681
|
-
CYAN: "\x1B[36m",
|
|
682
|
-
LIGHT_GREY: "\x1B[37m",
|
|
683
|
-
GREY: "\x1B[90m",
|
|
684
|
-
LIGHT_RED: "\x1B[91m",
|
|
685
|
-
LIGHT_GREEN: "\x1B[92m",
|
|
686
|
-
LIGHT_YELLOW: "\x1B[93m",
|
|
687
|
-
LIGHT_BLUE: "\x1B[94m",
|
|
688
|
-
LIGHT_MAGENTA: "\x1B[95m",
|
|
689
|
-
LIGHT_CYAN: "\x1B[96m",
|
|
690
|
-
WHITE: "\x1B[97m"
|
|
672
|
+
LIGHT_GREY: "\x1B[37m"
|
|
691
673
|
};
|
|
692
674
|
var LOG_LEVEL = /* @__PURE__ */ ((LOG_LEVEL2) => {
|
|
693
675
|
LOG_LEVEL2[LOG_LEVEL2["ERROR"] = 0] = "ERROR";
|
|
@@ -856,7 +838,7 @@ class PathEvent {
|
|
|
856
838
|
const parsedFind = makeArray(filter).map((pe) => new PathEvent(pe));
|
|
857
839
|
return parsedTarget.filter((t) => {
|
|
858
840
|
if (!t.fullPath && t.all) return true;
|
|
859
|
-
return !!parsedFind.find((f) => f.fullPath.startsWith(t.fullPath) && (f.all || t.all || t.methods.intersection(f.methods).length));
|
|
841
|
+
return !!parsedFind.find((f) => (t.fullPath.startsWith(f.fullPath) || f.fullPath.startsWith(t.fullPath)) && (f.all || t.all || t.methods.intersection(f.methods).length));
|
|
860
842
|
});
|
|
861
843
|
}
|
|
862
844
|
/**
|
|
@@ -986,6 +968,7 @@ class Api extends Http {
|
|
|
986
968
|
if (token) this.token = token;
|
|
987
969
|
}
|
|
988
970
|
}
|
|
971
|
+
/** Current API token */
|
|
989
972
|
get token() {
|
|
990
973
|
return this._token;
|
|
991
974
|
}
|
|
@@ -999,12 +982,21 @@ class Api extends Http {
|
|
|
999
982
|
}
|
|
1000
983
|
this.emit(PES`api/token:${token ? "u" : "d"}`, token);
|
|
1001
984
|
}
|
|
985
|
+
/**
|
|
986
|
+
* Fetch current Momentum status
|
|
987
|
+
* @return {Promise<Health>}
|
|
988
|
+
*/
|
|
1002
989
|
healthcheck() {
|
|
1003
990
|
return this.request({ url: "/api/healthcheck" }).then((resp) => {
|
|
1004
991
|
this.emit(PES`api/healthcheck:r`, resp);
|
|
1005
992
|
return resp;
|
|
1006
993
|
});
|
|
1007
994
|
}
|
|
995
|
+
/**
|
|
996
|
+
* Create API request
|
|
997
|
+
* @param {HttpRequestOptions} options Request options
|
|
998
|
+
* @return {Promise} Response
|
|
999
|
+
*/
|
|
1008
1000
|
request(options) {
|
|
1009
1001
|
const key = JSONSanitize(options);
|
|
1010
1002
|
const method = options.method == "GET" ? "r" : options.method == "POST" ? "c" : options.method == "DELETE" ? "d" : "u";
|
|
@@ -1038,6 +1030,11 @@ class Actions extends PathEventEmitter {
|
|
|
1038
1030
|
__publicField(this, "cache", new Cache("_id"));
|
|
1039
1031
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1040
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* All saved actions
|
|
1035
|
+
* @param {boolean} reload Will use cached response if false
|
|
1036
|
+
* @return {Promise<Action[]>} List of saved actions
|
|
1037
|
+
*/
|
|
1041
1038
|
async all(reload) {
|
|
1042
1039
|
if (!reload && this.cache.complete) return this.cache.all();
|
|
1043
1040
|
return this.api.request({ url: `/api/` + PES`actions` }).then((resp) => {
|
|
@@ -1046,6 +1043,11 @@ class Actions extends PathEventEmitter {
|
|
|
1046
1043
|
return resp;
|
|
1047
1044
|
});
|
|
1048
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Delete an existing action
|
|
1048
|
+
* @param {string} id Action ID
|
|
1049
|
+
* @return {Promise<void>} Delete complete
|
|
1050
|
+
*/
|
|
1049
1051
|
delete(id) {
|
|
1050
1052
|
if (!id) throw new Error("Cannot delete action, missing ID");
|
|
1051
1053
|
return this.api.request({ url: `/api/` + PES`actions/${id}`, method: "DELETE" }).then(() => {
|
|
@@ -1053,7 +1055,13 @@ class Actions extends PathEventEmitter {
|
|
|
1053
1055
|
this.emit(PES`actions/${id}:d`, id);
|
|
1054
1056
|
});
|
|
1055
1057
|
}
|
|
1056
|
-
|
|
1058
|
+
/**
|
|
1059
|
+
* Fetch action info
|
|
1060
|
+
* @param {string} id Action ID
|
|
1061
|
+
* @param {boolean} reload Will use cached response if false
|
|
1062
|
+
* @return {Promise<Action | null>} Requested action
|
|
1063
|
+
*/
|
|
1064
|
+
read(id, reload) {
|
|
1057
1065
|
if (!id) throw new Error("Cannot read action, missing ID");
|
|
1058
1066
|
const cached = this.cache.get(id);
|
|
1059
1067
|
if (!reload && cached) return Promise.resolve(cached);
|
|
@@ -1063,15 +1071,20 @@ class Actions extends PathEventEmitter {
|
|
|
1063
1071
|
return action;
|
|
1064
1072
|
});
|
|
1065
1073
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1074
|
+
/**
|
|
1075
|
+
* Manually trigger an actions execution
|
|
1076
|
+
* @param {string} id Action ID
|
|
1077
|
+
* @param {HttpRequestOptions} opts Additional arguments
|
|
1078
|
+
* @return {Promise<ActionResult>} Result of action
|
|
1079
|
+
*/
|
|
1080
|
+
runById(id, opts = {}) {
|
|
1073
1081
|
return this.api.request({ url: "/api/" + PES`actions/run-by-id/${id}`, method: "POST", ...opts });
|
|
1074
1082
|
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Update an action
|
|
1085
|
+
* @param {Action} action The new action
|
|
1086
|
+
* @return {Promise<Action>} Saved action
|
|
1087
|
+
*/
|
|
1075
1088
|
update(action) {
|
|
1076
1089
|
return this.api.request({
|
|
1077
1090
|
url: `/api/` + PES`actions/${action._id}`,
|
|
@@ -1090,6 +1103,12 @@ class Ai extends PathEventEmitter {
|
|
|
1090
1103
|
__publicField(this, "api");
|
|
1091
1104
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1092
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Ask the AI assistant a question
|
|
1108
|
+
* @param {string} question Users question
|
|
1109
|
+
* @param {any} context Additional data to aid response
|
|
1110
|
+
* @return {Promise<string>} AI's response
|
|
1111
|
+
*/
|
|
1093
1112
|
ask(question, context) {
|
|
1094
1113
|
if (!question) throw new Error("Cannot ask AI, missing question");
|
|
1095
1114
|
return this.api.request({ url: `/api/` + PES`ai`, method: "POST", body: {
|
|
@@ -1100,9 +1119,17 @@ class Ai extends PathEventEmitter {
|
|
|
1100
1119
|
return response;
|
|
1101
1120
|
});
|
|
1102
1121
|
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Clear AI assistant memory & context
|
|
1124
|
+
* @return {Promise<void>} Resolves once complete
|
|
1125
|
+
*/
|
|
1103
1126
|
clear() {
|
|
1104
1127
|
return this.api.request({ url: "/api/" + PES`ai`, method: "DELETE" }).then(() => this.emit(PES`ai:d`, this.api.token));
|
|
1105
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Current chat history
|
|
1131
|
+
* @return {Promise<{role: string, content: string}[]>}
|
|
1132
|
+
*/
|
|
1106
1133
|
history() {
|
|
1107
1134
|
return this.api.request({ url: "/api/" + PES`ai` }).then((resp) => {
|
|
1108
1135
|
this.emit(PES`ai:r`, resp);
|
|
@@ -1116,6 +1143,11 @@ class Analytics extends PathEventEmitter {
|
|
|
1116
1143
|
__publicField(this, "api");
|
|
1117
1144
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1118
1145
|
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Perform IP trace
|
|
1148
|
+
* @param {string} ip IP address to trace
|
|
1149
|
+
* @return {Promise<IpTrace>} Trace results
|
|
1150
|
+
*/
|
|
1119
1151
|
ipTrace(ip) {
|
|
1120
1152
|
if (!ip) throw new Error("Cannot trace, missing IP");
|
|
1121
1153
|
return this.api.request({ url: `/api/` + PES`analytics/trace/${ip}` }).then((resp) => {
|
|
@@ -1129,33 +1161,70 @@ class Token extends PathEventEmitter {
|
|
|
1129
1161
|
super();
|
|
1130
1162
|
this.api = api;
|
|
1131
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Fetch all tokens for user
|
|
1166
|
+
* @param {string} username User to search
|
|
1167
|
+
* @return {Promise<UserToken[]>} List of tokens
|
|
1168
|
+
*/
|
|
1132
1169
|
all(username) {
|
|
1133
1170
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${username}` }).then((resp) => {
|
|
1134
1171
|
this.emit(PES`token/${username}:r`, resp);
|
|
1135
1172
|
return resp;
|
|
1136
1173
|
});
|
|
1137
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Create a new user token
|
|
1177
|
+
* @param {{name: string, owner: string, expire: null | Date}} token Token settings
|
|
1178
|
+
* @return {Promise<UserToken>} Crated token
|
|
1179
|
+
*/
|
|
1138
1180
|
create(token) {
|
|
1139
1181
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${token.owner}`, body: token }).then((resp) => {
|
|
1140
1182
|
this.emit(PES`token/${token.owner}:c`, token);
|
|
1141
1183
|
return resp;
|
|
1142
1184
|
});
|
|
1143
1185
|
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Delete an existing user token
|
|
1188
|
+
* @param {string} id Token ID
|
|
1189
|
+
* @return {Promise<void>} Resolves once complete
|
|
1190
|
+
*/
|
|
1144
1191
|
delete(id) {
|
|
1145
1192
|
return this.api.request({ url: "/" + PES`api/auth/tokens/${id}`, method: "DELETE" }).then(() => this.emit(PES`token/${id}:d`, id));
|
|
1146
1193
|
}
|
|
1147
1194
|
}
|
|
1148
1195
|
class Totp {
|
|
1149
1196
|
constructor(api) {
|
|
1197
|
+
/**
|
|
1198
|
+
* Enable 2FA for user
|
|
1199
|
+
* @param {string} username User to reset
|
|
1200
|
+
* @return {Promise<void>} Resolves once complete
|
|
1201
|
+
*/
|
|
1150
1202
|
__publicField(this, "enable", this.reset);
|
|
1151
1203
|
this.api = api;
|
|
1152
1204
|
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Disable 2FA for user
|
|
1207
|
+
* @param {string} username User to disable 2FA for
|
|
1208
|
+
* @return {Promise<void>} Resolves once complete
|
|
1209
|
+
*/
|
|
1153
1210
|
disable(username) {
|
|
1154
1211
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "DELETE" });
|
|
1155
1212
|
}
|
|
1213
|
+
/**
|
|
1214
|
+
* Reset users 2FA
|
|
1215
|
+
* @param {string} username User to reset
|
|
1216
|
+
* @return {Promise<void>} Resolves once complete
|
|
1217
|
+
*/
|
|
1156
1218
|
reset(username) {
|
|
1157
1219
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, method: "POST" });
|
|
1158
1220
|
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Setup 2FA authentication method
|
|
1223
|
+
* @param {string} username User to setup
|
|
1224
|
+
* @param {string} method Authenticator type
|
|
1225
|
+
* @param {string | null} totp null to being process, 2FA code to validate method
|
|
1226
|
+
* @return {Promise<void>} Resolves once complete
|
|
1227
|
+
*/
|
|
1159
1228
|
setup(username, method = "app", totp) {
|
|
1160
1229
|
return this.api.request({ url: "/" + PES`api/auth/totp/${username}`, body: clean({
|
|
1161
1230
|
method,
|
|
@@ -1167,7 +1236,9 @@ class Auth extends PathEventEmitter {
|
|
|
1167
1236
|
constructor(api, opts = {}) {
|
|
1168
1237
|
super();
|
|
1169
1238
|
__publicField(this, "api");
|
|
1239
|
+
/** Manage user tokens */
|
|
1170
1240
|
__publicField(this, "token");
|
|
1241
|
+
/** Manage user 2FA */
|
|
1171
1242
|
__publicField(this, "totp");
|
|
1172
1243
|
__publicField(this, "_permissions", []);
|
|
1173
1244
|
__publicField(this, "_user");
|
|
@@ -1204,6 +1275,7 @@ class Auth extends PathEventEmitter {
|
|
|
1204
1275
|
else this.user = null;
|
|
1205
1276
|
});
|
|
1206
1277
|
}
|
|
1278
|
+
/** Get current user permissions */
|
|
1207
1279
|
get permissions() {
|
|
1208
1280
|
return this._permissions;
|
|
1209
1281
|
}
|
|
@@ -1211,19 +1283,33 @@ class Auth extends PathEventEmitter {
|
|
|
1211
1283
|
this._permissions = perms;
|
|
1212
1284
|
this.emit(PES`auth/permissions:u`, this._permissions);
|
|
1213
1285
|
}
|
|
1286
|
+
/** Get current user, undefined if not yet initialized */
|
|
1214
1287
|
get user() {
|
|
1215
1288
|
return this._user;
|
|
1216
1289
|
}
|
|
1290
|
+
/** Update user info without changing the session */
|
|
1217
1291
|
set user(user) {
|
|
1218
1292
|
if (!isEqual(this.user, user)) {
|
|
1219
1293
|
this._user = user ? user : null;
|
|
1220
1294
|
this.emit(PES`auth/user:u`, this._user);
|
|
1221
1295
|
}
|
|
1222
1296
|
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Check if origin is recognized & whitelisted
|
|
1299
|
+
* @param {string} host Origin to check
|
|
1300
|
+
* @return {Promise<void>} Resolves in known, 401 code otherwise
|
|
1301
|
+
*/
|
|
1223
1302
|
knownHost(host = location.origin) {
|
|
1224
1303
|
if (host.startsWith("/")) return Promise.resolve();
|
|
1225
1304
|
return this.api.request({ url: `/api/auth/known-host?host=${encodeURI(new URL(host).origin)}` });
|
|
1226
1305
|
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Login a user & return the account
|
|
1308
|
+
* @param {string} username username
|
|
1309
|
+
* @param {string} password user's password
|
|
1310
|
+
* @param {{totp: string, expire: null | number | Date}} opts 2FA code and expiry options (null to never expire)
|
|
1311
|
+
* @return {Promise<User | null>} User account on success
|
|
1312
|
+
*/
|
|
1227
1313
|
login(username, password, opts) {
|
|
1228
1314
|
if (!username || !password) throw new Error("Cannot login, missing username or password");
|
|
1229
1315
|
return this.api.request({
|
|
@@ -1242,6 +1328,11 @@ class Auth extends PathEventEmitter {
|
|
|
1242
1328
|
return user;
|
|
1243
1329
|
});
|
|
1244
1330
|
}
|
|
1331
|
+
/**
|
|
1332
|
+
* Login via Momentum single sign on
|
|
1333
|
+
* @param {string} host Host origin attempting to login
|
|
1334
|
+
* @return {Promise<string>} Token on success
|
|
1335
|
+
*/
|
|
1245
1336
|
loginRedirect(host = location.origin) {
|
|
1246
1337
|
return new Promise((res, rej) => {
|
|
1247
1338
|
var _a;
|
|
@@ -1251,10 +1342,10 @@ class Auth extends PathEventEmitter {
|
|
|
1251
1342
|
if (event.origin != origin || data.sender != origin) return;
|
|
1252
1343
|
if (!data.token) return rej("Unknown response from login");
|
|
1253
1344
|
done = true;
|
|
1254
|
-
this.api.token =
|
|
1345
|
+
this.api.token = data.token;
|
|
1255
1346
|
window.removeEventListener("message", listener);
|
|
1256
|
-
res(event.data.token);
|
|
1257
1347
|
win.close();
|
|
1348
|
+
res(data.token);
|
|
1258
1349
|
});
|
|
1259
1350
|
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.loginUrl}?redirect=postmessage&host=${host}`), "_blank");
|
|
1260
1351
|
if (!win) {
|
|
@@ -1266,18 +1357,26 @@ class Auth extends PathEventEmitter {
|
|
|
1266
1357
|
});
|
|
1267
1358
|
});
|
|
1268
1359
|
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Logout current user
|
|
1362
|
+
*/
|
|
1269
1363
|
logout() {
|
|
1270
1364
|
this.emit(PES`auth/logout:d`, this.user);
|
|
1271
1365
|
this.api.token = null;
|
|
1272
1366
|
this.user = null;
|
|
1273
1367
|
}
|
|
1274
|
-
|
|
1368
|
+
/**
|
|
1369
|
+
* Create a new user with login
|
|
1370
|
+
* @param {Partial<User> & {password: string}} user User data with password
|
|
1371
|
+
* @return {Promise<User>} Registered user data
|
|
1372
|
+
*/
|
|
1373
|
+
async register(user) {
|
|
1275
1374
|
var _a;
|
|
1276
|
-
if (!
|
|
1277
|
-
const
|
|
1278
|
-
if ((_a =
|
|
1279
|
-
this.emit(PES`auth/register:c`,
|
|
1280
|
-
return
|
|
1375
|
+
if (!user.username || !user.password) throw new Error("Cannot register user, missing username or password");
|
|
1376
|
+
const u = await this.api.request({ url: "/api/auth/register", body: { ...user } });
|
|
1377
|
+
if ((_a = u == null ? void 0 : u.image) == null ? void 0 : _a.startsWith("/")) u.image = `${this.api.url}${u.image}?token=${this.api.token}`;
|
|
1378
|
+
this.emit(PES`auth/register:c`, u);
|
|
1379
|
+
return u;
|
|
1281
1380
|
}
|
|
1282
1381
|
reset(emailOrPass, token) {
|
|
1283
1382
|
if (!emailOrPass) throw new Error("Cannot reset password, missing email or token");
|
|
@@ -1292,6 +1391,12 @@ class Auth extends PathEventEmitter {
|
|
|
1292
1391
|
this.emit(PES`auth/reset:${token ? "u" : "c"}`, token || emailOrPass);
|
|
1293
1392
|
});
|
|
1294
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Get session information
|
|
1396
|
+
* @param {string} token Token to fetch session info for
|
|
1397
|
+
* @param {boolean} set Set as current active session
|
|
1398
|
+
* @return {Promise<{token: string, user: User, permissions: string[], custom: any} | null>} Session information
|
|
1399
|
+
*/
|
|
1295
1400
|
async session(token, set = false) {
|
|
1296
1401
|
if (!token) token = this.api.token;
|
|
1297
1402
|
const session = await this.api.request({
|
|
@@ -1308,6 +1413,13 @@ class Auth extends PathEventEmitter {
|
|
|
1308
1413
|
}
|
|
1309
1414
|
return session;
|
|
1310
1415
|
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Update password for user
|
|
1418
|
+
* @param {string} username User to reset
|
|
1419
|
+
* @param {string} password New user password
|
|
1420
|
+
* @param {string} oldPassword Old password for validation
|
|
1421
|
+
* @return {Promise<void>} Resolves once complete
|
|
1422
|
+
*/
|
|
1311
1423
|
async updatePassword(username, password, oldPassword) {
|
|
1312
1424
|
if (!username || !password) throw new Error("Cannot update password, missing username or password");
|
|
1313
1425
|
return this.api.request({
|
|
@@ -1329,9 +1441,11 @@ class Client extends PathEventEmitter {
|
|
|
1329
1441
|
this.settings = settings;
|
|
1330
1442
|
this.pushSubscription.then((resp) => this.notifications = !!resp);
|
|
1331
1443
|
}
|
|
1444
|
+
/** Check if mobile device */
|
|
1332
1445
|
get mobile() {
|
|
1333
1446
|
return ["android", "ios"].includes(this.platform);
|
|
1334
1447
|
}
|
|
1448
|
+
/** Are notifications enabled */
|
|
1335
1449
|
get notifications() {
|
|
1336
1450
|
return this._notifications;
|
|
1337
1451
|
}
|
|
@@ -1339,6 +1453,7 @@ class Client extends PathEventEmitter {
|
|
|
1339
1453
|
this._notifications = enabled;
|
|
1340
1454
|
this.emit(PES`client/notifications:${enabled ? "c" : "d"}`, enabled);
|
|
1341
1455
|
}
|
|
1456
|
+
/** Get the current platform type */
|
|
1342
1457
|
get platform() {
|
|
1343
1458
|
if (!this._platform) {
|
|
1344
1459
|
const userAgent = navigator.userAgent || navigator.vendor;
|
|
@@ -1351,6 +1466,7 @@ class Client extends PathEventEmitter {
|
|
|
1351
1466
|
}
|
|
1352
1467
|
return this._platform;
|
|
1353
1468
|
}
|
|
1469
|
+
/** Get Push Subscription info */
|
|
1354
1470
|
get pushSubscription() {
|
|
1355
1471
|
var _a;
|
|
1356
1472
|
if (!((_a = navigator.serviceWorker) == null ? void 0 : _a.controller)) return Promise.resolve(null);
|
|
@@ -1359,115 +1475,86 @@ class Client extends PathEventEmitter {
|
|
|
1359
1475
|
return (_a2 = sw == null ? void 0 : sw.pushManager) == null ? void 0 : _a2.getSubscription();
|
|
1360
1476
|
});
|
|
1361
1477
|
}
|
|
1478
|
+
/** Check if running as a PWA */
|
|
1362
1479
|
get pwa() {
|
|
1363
1480
|
if (this._pwa == null)
|
|
1364
1481
|
this._pwa = matchMedia("(display-mode: standalone)").matches || (navigator == null ? void 0 : navigator.standalone) || document.referrer.includes("android-app://");
|
|
1365
1482
|
return this._pwa;
|
|
1366
1483
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
if (settings
|
|
1385
|
-
const meta = document.createElement("meta");
|
|
1386
|
-
meta.setAttribute("property", "og:url");
|
|
1387
|
-
meta.content = settings["public_url"];
|
|
1388
|
-
document.head.append(meta);
|
|
1389
|
-
}
|
|
1390
|
-
if (settings["description"]) {
|
|
1391
|
-
if (!document.querySelector('meta[property="og:description"]')) {
|
|
1392
|
-
const meta = document.createElement("meta");
|
|
1393
|
-
meta.setAttribute("property", "og:description");
|
|
1394
|
-
meta.content = settings["description"];
|
|
1395
|
-
document.head.append(meta);
|
|
1396
|
-
}
|
|
1397
|
-
if (!document.querySelector('meta[property="description"]')) {
|
|
1398
|
-
const meta = document.createElement("meta");
|
|
1399
|
-
meta.setAttribute("property", "description");
|
|
1400
|
-
meta.content = settings["description"];
|
|
1401
|
-
document.head.append(meta);
|
|
1402
|
-
}
|
|
1403
|
-
if (!document.querySelector('meta[property="twitter:card"]')) {
|
|
1404
|
-
const meta = document.createElement("meta");
|
|
1405
|
-
meta.setAttribute("property", "twitter:card");
|
|
1406
|
-
meta.content = settings["description"];
|
|
1407
|
-
document.head.append(meta);
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
if (settings["public_url"] && !document.querySelector('meta[property="og:image"]')) {
|
|
1411
|
-
const meta = document.createElement("meta");
|
|
1412
|
-
meta.setAttribute("property", "og:image");
|
|
1413
|
-
meta.content = settings["public_url"] + "/favicon.ico";
|
|
1414
|
-
document.head.append(meta);
|
|
1415
|
-
}
|
|
1416
|
-
if (!document.querySelector('meta[name="mobile-web-app-capable"]')) {
|
|
1417
|
-
const meta = document.createElement("meta");
|
|
1418
|
-
meta.name = "mobile-web-app-capable";
|
|
1419
|
-
meta.content = "yes";
|
|
1420
|
-
document.head.append(meta);
|
|
1421
|
-
}
|
|
1422
|
-
if (!document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]')) {
|
|
1423
|
-
const meta = document.createElement("meta");
|
|
1424
|
-
meta.name = "apple-mobile-web-app-status-bar-style";
|
|
1425
|
-
meta.content = "default";
|
|
1426
|
-
document.head.append(meta);
|
|
1427
|
-
}
|
|
1428
|
-
if (settings["title"] && !document.querySelector('meta[name="apple-mobile-web-app-title"]')) {
|
|
1429
|
-
const meta = document.createElement("meta");
|
|
1430
|
-
meta.name = "apple-mobile-web-app-title";
|
|
1431
|
-
meta.content = settings["title"];
|
|
1432
|
-
document.head.append(meta);
|
|
1433
|
-
}
|
|
1434
|
-
if (settings["public_url"] && !document.querySelector('link[rel="apple-touch-icon"]')) {
|
|
1435
|
-
const meta = document.createElement("link");
|
|
1436
|
-
meta.rel = "apple-touch-icon";
|
|
1437
|
-
meta.href = settings["public_url"] + "/favicon.ico";
|
|
1438
|
-
document.head.append(meta);
|
|
1439
|
-
}
|
|
1440
|
-
if (settings["public_url"] && !document.querySelector('link[rel="apple-touch-startup-image"]')) {
|
|
1441
|
-
const meta = document.createElement("link");
|
|
1442
|
-
meta.rel = "apple-touch-startup-image";
|
|
1443
|
-
meta.href = settings["public_url"] + "/favicon.ico";
|
|
1444
|
-
document.head.append(meta);
|
|
1445
|
-
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Inject the client theme settings, meta tags & PWA prompt
|
|
1486
|
+
* @param {boolean} reload Reload settings
|
|
1487
|
+
* @return {Promise<void>} Resolves on completion
|
|
1488
|
+
*/
|
|
1489
|
+
async inject(reload) {
|
|
1490
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1491
|
+
const meta = (key, name, value) => {
|
|
1492
|
+
const exists = document.querySelector(`meta[${key}="${name}"]`);
|
|
1493
|
+
if (value === void 0 || exists) return exists;
|
|
1494
|
+
const meta2 = document.createElement("meta");
|
|
1495
|
+
meta2.setAttribute(key, name);
|
|
1496
|
+
meta2.content = value;
|
|
1497
|
+
document.head.append(meta2);
|
|
1498
|
+
};
|
|
1499
|
+
if (!this.settings.cache.keys().length) reload = true;
|
|
1500
|
+
let settings = await (reload ? this.settings.all(false, true) : this.settings.cache);
|
|
1501
|
+
if (reload == null) this.settings.all(false, true).then(() => this.inject(false));
|
|
1446
1502
|
if (settings["title"]) document.querySelectorAll(".momentum-title").forEach((el) => el.innerText = settings["title"]);
|
|
1447
1503
|
if (settings["description"]) document.querySelectorAll(".momentum-description").forEach((el) => el.innerText = settings["description"]);
|
|
1448
1504
|
if (settings["version"]) document.querySelectorAll(".momentum-version").forEach((el) => el.innerText = settings["version"]);
|
|
1449
1505
|
if (settings["logo"]) document.querySelectorAll(".momentum-logo").forEach((el) => el.src = settings["logo"]);
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1506
|
+
meta("name", "description", settings["description"]);
|
|
1507
|
+
meta("itemprop", "name", settings["title"]);
|
|
1508
|
+
meta("itemprop", "description", settings["description"]);
|
|
1509
|
+
meta("itemprop", "image", `${settings["public_url"]}/favicon.png`);
|
|
1510
|
+
meta("property", "og:type", "website");
|
|
1511
|
+
meta("property", "og:url", settings["public_url"]);
|
|
1512
|
+
meta("property", "og:image", `${settings["public_url"]}/favicon.png`);
|
|
1513
|
+
meta("property", "og:title", settings["title"]);
|
|
1514
|
+
meta("property", "og:description", settings["description"]);
|
|
1515
|
+
meta("name", "twitter:card", "summary_large_image");
|
|
1516
|
+
meta("name", "twitter:title", settings["title"]);
|
|
1517
|
+
meta("name", "twitter:description", settings["description"]);
|
|
1518
|
+
meta("name", "twitter:image", `${settings["public_url"]}/favicon.png`);
|
|
1519
|
+
meta("name", "mobile-web-app-capable", "yes");
|
|
1520
|
+
meta("name", "apple-mobile-web-app-status-bar-style", "default");
|
|
1521
|
+
meta("name", "apple-mobile-web-app-title", settings["title"]);
|
|
1522
|
+
meta("name", "apple-touch-icon", `${settings["public_url"]}/favicon.png`);
|
|
1523
|
+
meta("name", "apple-touch-startup-image", `${settings["public_url"]}/favicon.png`);
|
|
1458
1524
|
if (settings["pwa"]) {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1525
|
+
if (!document.querySelector('link[rel="manifest"]')) {
|
|
1526
|
+
const link = document.createElement("link");
|
|
1527
|
+
link.setAttribute("rel", "manifest");
|
|
1528
|
+
link.setAttribute("href", this.settings.api.url + "/manifest.json");
|
|
1529
|
+
document.head.append(link);
|
|
1530
|
+
}
|
|
1463
1531
|
setTimeout(() => {
|
|
1464
1532
|
const dismissed = !!localStorage.getItem("momentum:install-prompt");
|
|
1465
1533
|
if (!dismissed && !this.pwa && this.mobile) this.pwaPrompt();
|
|
1466
|
-
},
|
|
1534
|
+
}, 6e4);
|
|
1467
1535
|
}
|
|
1536
|
+
meta("name", "theme-color", (_a = settings["theme"]) == null ? void 0 : _a.background);
|
|
1537
|
+
document.body.classList.add(((_b = settings["theme"]) == null ? void 0 : _b.darkMode) ? "theme-dark" : "theme-light");
|
|
1538
|
+
document.body.classList.remove(((_c = settings["theme"]) == null ? void 0 : _c.darkMode) ? "theme-light" : "theme-dark");
|
|
1539
|
+
const style = document.querySelector("style.momentum-theme") || document.createElement("style");
|
|
1540
|
+
style.classList.add("momentum-theme");
|
|
1541
|
+
style.innerHTML = `
|
|
1542
|
+
:root {
|
|
1543
|
+
--theme-backdrop: ${(_d = settings["theme"]) == null ? void 0 : _d.background} !important;
|
|
1544
|
+
--theme-primary: ${(_e = settings["theme"]) == null ? void 0 : _e.primary} !important;
|
|
1545
|
+
--theme-accent: ${(_f = settings["theme"]) == null ? void 0 : _f.accent} !important;
|
|
1546
|
+
--theme-contrast: ${blackOrWhite((_g = settings["theme"]) == null ? void 0 : _g.background)} !important;
|
|
1547
|
+
}
|
|
1548
|
+
`;
|
|
1549
|
+
if (!style.parentElement) document.head.append(style);
|
|
1468
1550
|
this.emit(PES`client/inject:c`, this.platform);
|
|
1469
1551
|
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Create UI prompt for user to install as PWA
|
|
1554
|
+
* @param platform Platform prompt, leave blank to auto-detect
|
|
1555
|
+
*/
|
|
1470
1556
|
pwaPrompt(platform) {
|
|
1557
|
+
if (document.querySelector(".momentum-pwa-prompt")) return;
|
|
1471
1558
|
const url = this.settings.api.url;
|
|
1472
1559
|
const settings = this.settings.cache;
|
|
1473
1560
|
const android = (platform || this.platform) == "android";
|
|
@@ -1574,7 +1661,7 @@ class Client extends PathEventEmitter {
|
|
|
1574
1661
|
</div>`;
|
|
1575
1662
|
const close = document.createElement("button");
|
|
1576
1663
|
close.classList.add("momentum-pwa-prompt-close");
|
|
1577
|
-
close.innerText = "
|
|
1664
|
+
close.innerText = "x";
|
|
1578
1665
|
close.onclick = () => {
|
|
1579
1666
|
prompt.classList.add("exit");
|
|
1580
1667
|
backdrop.classList.add("exit");
|
|
@@ -1590,6 +1677,10 @@ class Client extends PathEventEmitter {
|
|
|
1590
1677
|
document.body.append(backdrop);
|
|
1591
1678
|
this.emit(PES`client/pwa:c`, platform);
|
|
1592
1679
|
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Enable device notifications
|
|
1682
|
+
* @return {Promise<null>} Resolves on success
|
|
1683
|
+
*/
|
|
1593
1684
|
async enableNotifications() {
|
|
1594
1685
|
const granted = await Notification.requestPermission();
|
|
1595
1686
|
if (!granted) return null;
|
|
@@ -1600,6 +1691,10 @@ class Client extends PathEventEmitter {
|
|
|
1600
1691
|
})).toJSON();
|
|
1601
1692
|
return this.api.request({ url: "/api/notifications", body: subscription }).then(() => this.notifications = true);
|
|
1602
1693
|
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Disable device notifications
|
|
1696
|
+
* @return {Promise<void>} Resolves on success
|
|
1697
|
+
*/
|
|
1603
1698
|
async disableNotifications() {
|
|
1604
1699
|
var _a;
|
|
1605
1700
|
const subscription = await this.pushSubscription;
|
|
@@ -1609,11 +1704,36 @@ class Client extends PathEventEmitter {
|
|
|
1609
1704
|
} }).then(() => this.notifications = false);
|
|
1610
1705
|
}
|
|
1611
1706
|
}
|
|
1707
|
+
class Schemas extends PathEventEmitter {
|
|
1708
|
+
constructor(api) {
|
|
1709
|
+
super();
|
|
1710
|
+
this.api = api;
|
|
1711
|
+
}
|
|
1712
|
+
delete(path) {
|
|
1713
|
+
if (!path) throw new Error("Cannot delete schema, missing collection path");
|
|
1714
|
+
return this.api.request({ url: `/api/` + PES`schema/${path}`, method: "DELETE" }).then(() => this.emit(PES`schema/${path}:d`, path));
|
|
1715
|
+
}
|
|
1716
|
+
read(pathOrTree) {
|
|
1717
|
+
return this.api.request({ url: "/api/" + PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
1718
|
+
this.emit(PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
1719
|
+
return resp;
|
|
1720
|
+
});
|
|
1721
|
+
}
|
|
1722
|
+
update(schema) {
|
|
1723
|
+
if (!schema.path) throw new Error("Cannot update schema, missing collection path");
|
|
1724
|
+
return this.api.request({ url: "/api/" + PES`schema/${schema.path}`, body: schema }).then((resp) => {
|
|
1725
|
+
this.emit(PES`schema/${schema.path}:${schema._id ? "u" : "c"}`, resp);
|
|
1726
|
+
return resp;
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1612
1730
|
class Data extends PathEventEmitter {
|
|
1613
1731
|
constructor(api) {
|
|
1614
1732
|
super();
|
|
1615
1733
|
__publicField(this, "api");
|
|
1734
|
+
__publicField(this, "schema");
|
|
1616
1735
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1736
|
+
this.schema = new Schemas(this.api);
|
|
1617
1737
|
}
|
|
1618
1738
|
create(collection, document2) {
|
|
1619
1739
|
if (!collection || !document2) throw new Error("Cannot create document, missing collection or document");
|
|
@@ -1659,24 +1779,6 @@ class Data extends PathEventEmitter {
|
|
|
1659
1779
|
return resp;
|
|
1660
1780
|
});
|
|
1661
1781
|
}
|
|
1662
|
-
// Schema ==========================================================================================================
|
|
1663
|
-
deleteSchema(path) {
|
|
1664
|
-
if (!path) throw new Error("Cannot delete schema, missing collection path");
|
|
1665
|
-
return this.api.request({ url: `/api/` + PES`schema/${path}`, method: "DELETE" }).then(() => this.emit(PES`schema/${path}:d`, path));
|
|
1666
|
-
}
|
|
1667
|
-
readSchema(pathOrTree) {
|
|
1668
|
-
return this.api.request({ url: "/api/" + PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}` + (pathOrTree === true ? `?tree=${pathOrTree}` : "") }).then((resp) => {
|
|
1669
|
-
this.emit(PES`schema/${typeof pathOrTree == "string" ? pathOrTree : ""}:r`, resp);
|
|
1670
|
-
return resp;
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1673
|
-
updateSchema(schema) {
|
|
1674
|
-
if (!schema.path) throw new Error("Cannot update schema, missing collection path");
|
|
1675
|
-
return this.api.request({ url: "/api/" + PES`schema/${schema.path}`, body: schema }).then((resp) => {
|
|
1676
|
-
this.emit(PES`schema/${schema.path}:${schema._id ? "u" : "c"}`, resp);
|
|
1677
|
-
return resp;
|
|
1678
|
-
});
|
|
1679
|
-
}
|
|
1680
1782
|
}
|
|
1681
1783
|
class Email extends PathEventEmitter {
|
|
1682
1784
|
constructor(api) {
|
|
@@ -1684,6 +1786,11 @@ class Email extends PathEventEmitter {
|
|
|
1684
1786
|
__publicField(this, "api");
|
|
1685
1787
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1686
1788
|
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Send Email
|
|
1791
|
+
* @param {Mail} email Email to send
|
|
1792
|
+
* @return {Promise<any>} Response
|
|
1793
|
+
*/
|
|
1687
1794
|
send(email) {
|
|
1688
1795
|
if (!email.to && !email.bcc || !email.body) throw new Error("Cannot send email, missing address or body");
|
|
1689
1796
|
return this.api.request({ url: "/api/email", body: email }).then((response) => {
|
|
@@ -1894,46 +2001,103 @@ ${log}`;
|
|
|
1894
2001
|
}
|
|
1895
2002
|
}
|
|
1896
2003
|
class Payments extends PathEventEmitter {
|
|
1897
|
-
constructor(api,
|
|
2004
|
+
constructor(api, opts = {}) {
|
|
1898
2005
|
super();
|
|
1899
2006
|
__publicField(this, "api");
|
|
2007
|
+
__publicField(this, "loaded", false);
|
|
1900
2008
|
__publicField(this, "stripe");
|
|
2009
|
+
__publicField(this, "token");
|
|
2010
|
+
this.opts = opts;
|
|
1901
2011
|
this.api = typeof api == "string" ? new Api(api) : api;
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
this.stripe = Stripe(secret);
|
|
1906
|
-
} catch (err) {
|
|
1907
|
-
if (retry > 0) setTimeout(() => setup(retry--), 250);
|
|
1908
|
-
else console.warn("Stripe failed, did you add the library & setup your API key?", err);
|
|
1909
|
-
}
|
|
2012
|
+
this.opts = {
|
|
2013
|
+
paymentUrl: this.api.url + "/ui/#/payment",
|
|
2014
|
+
...this.opts
|
|
1910
2015
|
};
|
|
1911
|
-
setup();
|
|
1912
2016
|
}
|
|
1913
|
-
async
|
|
1914
|
-
if (!
|
|
2017
|
+
async checkout(cart, opts = {}) {
|
|
2018
|
+
if (!(cart == null ? void 0 : cart.length)) throw new Error("Please add items to cart`");
|
|
1915
2019
|
const request = await this.api.request({ url: "/api/payments", body: {
|
|
1916
|
-
|
|
1917
|
-
|
|
2020
|
+
cart,
|
|
2021
|
+
recipient: opts == null ? void 0 : opts.recipient,
|
|
2022
|
+
invoice: opts == null ? void 0 : opts.invoice,
|
|
2023
|
+
extra: opts == null ? void 0 : opts.extra
|
|
1918
2024
|
} });
|
|
1919
|
-
this.emit(PES`payments:c`, request.
|
|
1920
|
-
return request.
|
|
2025
|
+
this.emit(PES`payments:c`, request.token);
|
|
2026
|
+
return request.token;
|
|
1921
2027
|
}
|
|
1922
|
-
async
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
2028
|
+
async init() {
|
|
2029
|
+
if (!this.stripe) this.stripe = await new Promise((res) => {
|
|
2030
|
+
if (this.loaded || this.stripe) return res(window["Stripe"]);
|
|
2031
|
+
const script = document.createElement("script");
|
|
2032
|
+
script.src = "https://js.stripe.com/v3/";
|
|
2033
|
+
script.setAttribute("crossorigin", "anonymous");
|
|
2034
|
+
script.onload = () => res(window["Stripe"]);
|
|
2035
|
+
document.head.appendChild(script);
|
|
1930
2036
|
});
|
|
2037
|
+
return this.stripe(this.token);
|
|
1931
2038
|
}
|
|
1932
2039
|
async history(username) {
|
|
1933
|
-
const history = await this.api.request({ url: `/api
|
|
2040
|
+
const history = await this.api.request({ url: `/api/payments/${username || ""}` });
|
|
1934
2041
|
this.emit(PES`payments/${username}:r`, history);
|
|
1935
2042
|
return history;
|
|
1936
2043
|
}
|
|
2044
|
+
async products(id) {
|
|
2045
|
+
return this.api.request({ url: `/api/payments/products/${id || ""}` }).then((resp) => {
|
|
2046
|
+
this.emit(PES`products/${id}:r`, resp);
|
|
2047
|
+
return resp;
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
async payment(card, token) {
|
|
2051
|
+
const client = await this.init();
|
|
2052
|
+
return client.confirmPayment({
|
|
2053
|
+
clientSecret: token,
|
|
2054
|
+
confirmParams: {
|
|
2055
|
+
payment_method: {
|
|
2056
|
+
card: { ...card, details: void 0 },
|
|
2057
|
+
billing_details: card.details || {}
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
async paymentForm(element, token) {
|
|
2063
|
+
const client = await this.init();
|
|
2064
|
+
const form = client.elements({ clientSecret: token });
|
|
2065
|
+
form.create("payment").mount(element);
|
|
2066
|
+
return (redirect = location.href) => client.confirmPayment({
|
|
2067
|
+
elements: form,
|
|
2068
|
+
redirect: "if_required",
|
|
2069
|
+
confirmParams: { return_url: redirect + "?payment_status=success" }
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2072
|
+
/**
|
|
2073
|
+
* Complete payment via Momentum's payment page
|
|
2074
|
+
* @param {string} token Stripe payment intent secret
|
|
2075
|
+
* @param {string} host Host origin attempting to login
|
|
2076
|
+
* @return {Promise<string>} Token on success
|
|
2077
|
+
*/
|
|
2078
|
+
paymentRedirect(token, host = location.origin) {
|
|
2079
|
+
return new Promise(async (res, rej) => {
|
|
2080
|
+
var _a;
|
|
2081
|
+
let origin = new URL(this.opts.paymentUrl).origin, done = false, listener, win;
|
|
2082
|
+
window.addEventListener("message", listener = (event) => {
|
|
2083
|
+
const data = (event == null ? void 0 : event.data) || {};
|
|
2084
|
+
if (event.origin != origin || data.sender != origin) return;
|
|
2085
|
+
if (!data.response) return rej("Unknown response from payment page");
|
|
2086
|
+
done = true;
|
|
2087
|
+
window.removeEventListener("message", listener);
|
|
2088
|
+
win.close();
|
|
2089
|
+
res(data.response);
|
|
2090
|
+
});
|
|
2091
|
+
win = window.open(encodeURI(`${(_a = this.opts) == null ? void 0 : _a.paymentUrl}?token=${token}&host=${host}`), "_blank");
|
|
2092
|
+
if (!win) {
|
|
2093
|
+
window.removeEventListener("message", listener);
|
|
2094
|
+
return rej("Unable to open payment page");
|
|
2095
|
+
}
|
|
2096
|
+
win.addEventListener("close", () => {
|
|
2097
|
+
if (!done) rej("Window closed before payment was complete");
|
|
2098
|
+
});
|
|
2099
|
+
});
|
|
2100
|
+
}
|
|
1937
2101
|
}
|
|
1938
2102
|
class Pdf extends PathEventEmitter {
|
|
1939
2103
|
constructor(api) {
|
|
@@ -2254,7 +2418,7 @@ class Momentum extends PathEventEmitter {
|
|
|
2254
2418
|
this.forms = new Forms(this.api);
|
|
2255
2419
|
this.groups = new Groups(this.api);
|
|
2256
2420
|
this.logger = new Logger(this.api, (opts == null ? void 0 : opts.app) || "client", opts == null ? void 0 : opts.logLevel);
|
|
2257
|
-
|
|
2421
|
+
this.payments = new Payments(this.api);
|
|
2258
2422
|
this.pdf = new Pdf(this.api);
|
|
2259
2423
|
this.phone = new Phone(this.api);
|
|
2260
2424
|
this.settings = new Settings(this.api);
|
|
@@ -2273,7 +2437,7 @@ class Momentum extends PathEventEmitter {
|
|
|
2273
2437
|
this.relayEvents(this.email);
|
|
2274
2438
|
this.relayEvents(this.groups);
|
|
2275
2439
|
this.relayEvents(this.logger);
|
|
2276
|
-
|
|
2440
|
+
this.relayEvents(this.payments);
|
|
2277
2441
|
this.relayEvents(this.pdf);
|
|
2278
2442
|
this.relayEvents(this.phone);
|
|
2279
2443
|
this.relayEvents(this.settings);
|
|
@@ -2285,8 +2449,12 @@ class Momentum extends PathEventEmitter {
|
|
|
2285
2449
|
const cached = this.users.cache.get(this.auth.user.username);
|
|
2286
2450
|
if (cached) this.auth.user = cached;
|
|
2287
2451
|
});
|
|
2288
|
-
|
|
2289
|
-
|
|
2452
|
+
this.settings.on("settings:r", (event, value) => {
|
|
2453
|
+
var _a;
|
|
2454
|
+
this.payments.token = ((_a = value["stripe_token"]) == null ? void 0 : _a.value) || value["stripe_token"];
|
|
2455
|
+
});
|
|
2456
|
+
if ((opts == null ? void 0 : opts.worker) !== false && "serviceWorker" in navigator) {
|
|
2457
|
+
navigator.serviceWorker.register((opts == null ? void 0 : opts.worker) || "/momentum.worker.js").catch(() => console.warn("Unable to load momentum worker, some features may be limited."));
|
|
2290
2458
|
}
|
|
2291
2459
|
}
|
|
2292
2460
|
}
|