@getstrata/core 0.5.4 → 0.5.6
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/README.md +3 -0
- package/dist/core/crypto/nonCryptographicHash.d.ts +2 -0
- package/dist/core/http/cookies.d.ts +4 -0
- package/dist/core/http/csrfProtection.d.ts +12 -0
- package/dist/entries/auth/guard.js +20 -20
- package/dist/entries/auth/membershipService.js +3 -0
- package/dist/entries/database.js +20 -20
- package/dist/entries/http/csrfToken.js +49 -65
- package/dist/entries/http/etag.js +6 -4
- package/dist/entries/http/webErrorResponse.js +73 -87
- package/dist/entries/http.js +83 -90
- package/dist/entries/queue/createAppQueue.js +23 -20
- package/dist/entries/queue/publicQueue.js +20 -20
- package/dist/entries/queue/queueMetrics.js +23 -20
- package/dist/entries/view.js +73 -87
- package/dist/framework/public-api.d.ts +5 -0
- package/dist/index.js +205 -180
- package/package.json +4 -1
|
@@ -119,6 +119,9 @@ function resolveService(dependencies, token) {
|
|
|
119
119
|
|
|
120
120
|
// ../../src/bootstrap/applicationRegistry.ts
|
|
121
121
|
var activeContext;
|
|
122
|
+
function setActiveApplicationContext(context) {
|
|
123
|
+
activeContext = context;
|
|
124
|
+
}
|
|
122
125
|
function requireActiveApplicationContext() {
|
|
123
126
|
if (!activeContext) {
|
|
124
127
|
throw new Error("The application context has not been bootstrapped.");
|
|
@@ -1748,26 +1751,26 @@ class Model {
|
|
|
1748
1751
|
throw new Error(`${this.constructor.name}.primaryKey() is not implemented.`);
|
|
1749
1752
|
}
|
|
1750
1753
|
static primaryKeyField() {
|
|
1751
|
-
return resolveModelRepository(
|
|
1754
|
+
return resolveModelRepository(Model).getTable().primaryKey;
|
|
1752
1755
|
}
|
|
1753
1756
|
static hydrateAttributes(attributes) {
|
|
1754
|
-
const casts = modelStatics(
|
|
1757
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1755
1758
|
return applyCasts(attributes, casts, "hydrate");
|
|
1756
1759
|
}
|
|
1757
1760
|
static dehydrateAttributes(attributes) {
|
|
1758
|
-
const casts = modelStatics(
|
|
1761
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1759
1762
|
return applyCasts(attributes, casts, "dehydrate");
|
|
1760
1763
|
}
|
|
1761
1764
|
static fromRecord(record, repository, exists = true) {
|
|
1762
|
-
const statics = modelStatics(
|
|
1765
|
+
const statics = modelStatics(Model);
|
|
1763
1766
|
const hydrated = statics.hydrateAttributes(record);
|
|
1764
1767
|
return new statics(hydrated, repository, exists);
|
|
1765
1768
|
}
|
|
1766
1769
|
static boot() {}
|
|
1767
1770
|
static addGlobalScope(_name, scope) {
|
|
1768
|
-
ensureBooted(
|
|
1769
|
-
const existing = modelGlobalScopes.get(
|
|
1770
|
-
modelGlobalScopes.set(
|
|
1771
|
+
ensureBooted(Model);
|
|
1772
|
+
const existing = modelGlobalScopes.get(Model) ?? [];
|
|
1773
|
+
modelGlobalScopes.set(Model, [
|
|
1771
1774
|
...existing,
|
|
1772
1775
|
scope
|
|
1773
1776
|
]);
|
|
@@ -1777,17 +1780,17 @@ class Model {
|
|
|
1777
1780
|
}
|
|
1778
1781
|
static query() {
|
|
1779
1782
|
ensureBooted(this);
|
|
1780
|
-
const repository = resolveModelRepository(
|
|
1783
|
+
const repository = resolveModelRepository(Model);
|
|
1781
1784
|
let query = repository.query();
|
|
1782
|
-
for (const scope of getGlobalScopes(
|
|
1785
|
+
for (const scope of getGlobalScopes(Model)) {
|
|
1783
1786
|
query = scope(query);
|
|
1784
1787
|
}
|
|
1785
1788
|
return query;
|
|
1786
1789
|
}
|
|
1787
1790
|
static async create(attributes) {
|
|
1788
1791
|
const statics = modelStatics(this);
|
|
1789
|
-
ensureBooted(
|
|
1790
|
-
const repository = resolveModelRepository(
|
|
1792
|
+
ensureBooted(Model);
|
|
1793
|
+
const repository = resolveModelRepository(Model);
|
|
1791
1794
|
const table = repository.getTable();
|
|
1792
1795
|
const timestamps = statics.$timestamps ?? true;
|
|
1793
1796
|
const assignable = filterMassAssignable(statics.$fillable, statics.$guarded, attributes);
|
|
@@ -1797,23 +1800,23 @@ class Model {
|
|
|
1797
1800
|
return statics.fromRecord(record, repository, true);
|
|
1798
1801
|
}
|
|
1799
1802
|
static async find(id) {
|
|
1800
|
-
const statics = modelStatics(
|
|
1801
|
-
const repository = resolveModelRepository(
|
|
1803
|
+
const statics = modelStatics(Model);
|
|
1804
|
+
const repository = resolveModelRepository(Model);
|
|
1802
1805
|
const primaryKey = repository.getTable().primaryKey;
|
|
1803
|
-
const record = await Model.query.call(
|
|
1806
|
+
const record = await Model.query.call(Model).where({ [primaryKey]: id }).first();
|
|
1804
1807
|
return record ? statics.fromRecord(record, repository, true) : null;
|
|
1805
1808
|
}
|
|
1806
1809
|
static async findOrFail(id, errorFactory) {
|
|
1807
|
-
const model = await Model.find.call(
|
|
1810
|
+
const model = await Model.find.call(Model, id);
|
|
1808
1811
|
if (model) {
|
|
1809
1812
|
return model;
|
|
1810
1813
|
}
|
|
1811
|
-
throw errorFactory?.(id) ?? new NotFoundError(`${
|
|
1814
|
+
throw errorFactory?.(id) ?? new NotFoundError(`${Model.name} ${String(id)} not found.`);
|
|
1812
1815
|
}
|
|
1813
1816
|
static async all(options = {}) {
|
|
1814
1817
|
const statics = modelStatics(this);
|
|
1815
|
-
const repository = resolveModelRepository(
|
|
1816
|
-
let query = Model.query.call(
|
|
1818
|
+
const repository = resolveModelRepository(Model);
|
|
1819
|
+
let query = Model.query.call(Model);
|
|
1817
1820
|
if (options.orderBy) {
|
|
1818
1821
|
query = query.orderBy(options.orderBy);
|
|
1819
1822
|
}
|
|
@@ -1825,8 +1828,8 @@ class Model {
|
|
|
1825
1828
|
}
|
|
1826
1829
|
static async firstWhere(where, options = {}) {
|
|
1827
1830
|
const statics = modelStatics(this);
|
|
1828
|
-
const repository = resolveModelRepository(
|
|
1829
|
-
let query = Model.query.call(
|
|
1831
|
+
const repository = resolveModelRepository(Model);
|
|
1832
|
+
let query = Model.query.call(Model).where(where);
|
|
1830
1833
|
if (options.orderBy) {
|
|
1831
1834
|
query = query.orderBy(options.orderBy);
|
|
1832
1835
|
}
|
|
@@ -1353,26 +1353,26 @@ class Model {
|
|
|
1353
1353
|
throw new Error(`${this.constructor.name}.primaryKey() is not implemented.`);
|
|
1354
1354
|
}
|
|
1355
1355
|
static primaryKeyField() {
|
|
1356
|
-
return resolveModelRepository(
|
|
1356
|
+
return resolveModelRepository(Model).getTable().primaryKey;
|
|
1357
1357
|
}
|
|
1358
1358
|
static hydrateAttributes(attributes) {
|
|
1359
|
-
const casts = modelStatics(
|
|
1359
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1360
1360
|
return applyCasts(attributes, casts, "hydrate");
|
|
1361
1361
|
}
|
|
1362
1362
|
static dehydrateAttributes(attributes) {
|
|
1363
|
-
const casts = modelStatics(
|
|
1363
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1364
1364
|
return applyCasts(attributes, casts, "dehydrate");
|
|
1365
1365
|
}
|
|
1366
1366
|
static fromRecord(record, repository, exists = true) {
|
|
1367
|
-
const statics = modelStatics(
|
|
1367
|
+
const statics = modelStatics(Model);
|
|
1368
1368
|
const hydrated = statics.hydrateAttributes(record);
|
|
1369
1369
|
return new statics(hydrated, repository, exists);
|
|
1370
1370
|
}
|
|
1371
1371
|
static boot() {}
|
|
1372
1372
|
static addGlobalScope(_name, scope) {
|
|
1373
|
-
ensureBooted(
|
|
1374
|
-
const existing = modelGlobalScopes.get(
|
|
1375
|
-
modelGlobalScopes.set(
|
|
1373
|
+
ensureBooted(Model);
|
|
1374
|
+
const existing = modelGlobalScopes.get(Model) ?? [];
|
|
1375
|
+
modelGlobalScopes.set(Model, [
|
|
1376
1376
|
...existing,
|
|
1377
1377
|
scope
|
|
1378
1378
|
]);
|
|
@@ -1382,17 +1382,17 @@ class Model {
|
|
|
1382
1382
|
}
|
|
1383
1383
|
static query() {
|
|
1384
1384
|
ensureBooted(this);
|
|
1385
|
-
const repository = resolveModelRepository(
|
|
1385
|
+
const repository = resolveModelRepository(Model);
|
|
1386
1386
|
let query = repository.query();
|
|
1387
|
-
for (const scope of getGlobalScopes(
|
|
1387
|
+
for (const scope of getGlobalScopes(Model)) {
|
|
1388
1388
|
query = scope(query);
|
|
1389
1389
|
}
|
|
1390
1390
|
return query;
|
|
1391
1391
|
}
|
|
1392
1392
|
static async create(attributes) {
|
|
1393
1393
|
const statics = modelStatics(this);
|
|
1394
|
-
ensureBooted(
|
|
1395
|
-
const repository = resolveModelRepository(
|
|
1394
|
+
ensureBooted(Model);
|
|
1395
|
+
const repository = resolveModelRepository(Model);
|
|
1396
1396
|
const table = repository.getTable();
|
|
1397
1397
|
const timestamps = statics.$timestamps ?? true;
|
|
1398
1398
|
const assignable = filterMassAssignable(statics.$fillable, statics.$guarded, attributes);
|
|
@@ -1402,23 +1402,23 @@ class Model {
|
|
|
1402
1402
|
return statics.fromRecord(record, repository, true);
|
|
1403
1403
|
}
|
|
1404
1404
|
static async find(id) {
|
|
1405
|
-
const statics = modelStatics(
|
|
1406
|
-
const repository = resolveModelRepository(
|
|
1405
|
+
const statics = modelStatics(Model);
|
|
1406
|
+
const repository = resolveModelRepository(Model);
|
|
1407
1407
|
const primaryKey = repository.getTable().primaryKey;
|
|
1408
|
-
const record = await Model.query.call(
|
|
1408
|
+
const record = await Model.query.call(Model).where({ [primaryKey]: id }).first();
|
|
1409
1409
|
return record ? statics.fromRecord(record, repository, true) : null;
|
|
1410
1410
|
}
|
|
1411
1411
|
static async findOrFail(id, errorFactory) {
|
|
1412
|
-
const model = await Model.find.call(
|
|
1412
|
+
const model = await Model.find.call(Model, id);
|
|
1413
1413
|
if (model) {
|
|
1414
1414
|
return model;
|
|
1415
1415
|
}
|
|
1416
|
-
throw errorFactory?.(id) ?? new NotFoundError(`${
|
|
1416
|
+
throw errorFactory?.(id) ?? new NotFoundError(`${Model.name} ${String(id)} not found.`);
|
|
1417
1417
|
}
|
|
1418
1418
|
static async all(options = {}) {
|
|
1419
1419
|
const statics = modelStatics(this);
|
|
1420
|
-
const repository = resolveModelRepository(
|
|
1421
|
-
let query = Model.query.call(
|
|
1420
|
+
const repository = resolveModelRepository(Model);
|
|
1421
|
+
let query = Model.query.call(Model);
|
|
1422
1422
|
if (options.orderBy) {
|
|
1423
1423
|
query = query.orderBy(options.orderBy);
|
|
1424
1424
|
}
|
|
@@ -1430,8 +1430,8 @@ class Model {
|
|
|
1430
1430
|
}
|
|
1431
1431
|
static async firstWhere(where, options = {}) {
|
|
1432
1432
|
const statics = modelStatics(this);
|
|
1433
|
-
const repository = resolveModelRepository(
|
|
1434
|
-
let query = Model.query.call(
|
|
1433
|
+
const repository = resolveModelRepository(Model);
|
|
1434
|
+
let query = Model.query.call(Model).where(where);
|
|
1435
1435
|
if (options.orderBy) {
|
|
1436
1436
|
query = query.orderBy(options.orderBy);
|
|
1437
1437
|
}
|
|
@@ -129,6 +129,9 @@ function resolveService(dependencies, token) {
|
|
|
129
129
|
|
|
130
130
|
// ../../src/bootstrap/applicationRegistry.ts
|
|
131
131
|
var activeContext;
|
|
132
|
+
function setActiveApplicationContext(context) {
|
|
133
|
+
activeContext = context;
|
|
134
|
+
}
|
|
132
135
|
function requireActiveApplicationContext() {
|
|
133
136
|
if (!activeContext) {
|
|
134
137
|
throw new Error("The application context has not been bootstrapped.");
|
|
@@ -1758,26 +1761,26 @@ class Model {
|
|
|
1758
1761
|
throw new Error(`${this.constructor.name}.primaryKey() is not implemented.`);
|
|
1759
1762
|
}
|
|
1760
1763
|
static primaryKeyField() {
|
|
1761
|
-
return resolveModelRepository(
|
|
1764
|
+
return resolveModelRepository(Model).getTable().primaryKey;
|
|
1762
1765
|
}
|
|
1763
1766
|
static hydrateAttributes(attributes) {
|
|
1764
|
-
const casts = modelStatics(
|
|
1767
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1765
1768
|
return applyCasts(attributes, casts, "hydrate");
|
|
1766
1769
|
}
|
|
1767
1770
|
static dehydrateAttributes(attributes) {
|
|
1768
|
-
const casts = modelStatics(
|
|
1771
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1769
1772
|
return applyCasts(attributes, casts, "dehydrate");
|
|
1770
1773
|
}
|
|
1771
1774
|
static fromRecord(record, repository, exists = true) {
|
|
1772
|
-
const statics = modelStatics(
|
|
1775
|
+
const statics = modelStatics(Model);
|
|
1773
1776
|
const hydrated = statics.hydrateAttributes(record);
|
|
1774
1777
|
return new statics(hydrated, repository, exists);
|
|
1775
1778
|
}
|
|
1776
1779
|
static boot() {}
|
|
1777
1780
|
static addGlobalScope(_name, scope) {
|
|
1778
|
-
ensureBooted(
|
|
1779
|
-
const existing = modelGlobalScopes.get(
|
|
1780
|
-
modelGlobalScopes.set(
|
|
1781
|
+
ensureBooted(Model);
|
|
1782
|
+
const existing = modelGlobalScopes.get(Model) ?? [];
|
|
1783
|
+
modelGlobalScopes.set(Model, [
|
|
1781
1784
|
...existing,
|
|
1782
1785
|
scope
|
|
1783
1786
|
]);
|
|
@@ -1787,17 +1790,17 @@ class Model {
|
|
|
1787
1790
|
}
|
|
1788
1791
|
static query() {
|
|
1789
1792
|
ensureBooted(this);
|
|
1790
|
-
const repository = resolveModelRepository(
|
|
1793
|
+
const repository = resolveModelRepository(Model);
|
|
1791
1794
|
let query = repository.query();
|
|
1792
|
-
for (const scope of getGlobalScopes(
|
|
1795
|
+
for (const scope of getGlobalScopes(Model)) {
|
|
1793
1796
|
query = scope(query);
|
|
1794
1797
|
}
|
|
1795
1798
|
return query;
|
|
1796
1799
|
}
|
|
1797
1800
|
static async create(attributes) {
|
|
1798
1801
|
const statics = modelStatics(this);
|
|
1799
|
-
ensureBooted(
|
|
1800
|
-
const repository = resolveModelRepository(
|
|
1802
|
+
ensureBooted(Model);
|
|
1803
|
+
const repository = resolveModelRepository(Model);
|
|
1801
1804
|
const table = repository.getTable();
|
|
1802
1805
|
const timestamps = statics.$timestamps ?? true;
|
|
1803
1806
|
const assignable = filterMassAssignable(statics.$fillable, statics.$guarded, attributes);
|
|
@@ -1807,23 +1810,23 @@ class Model {
|
|
|
1807
1810
|
return statics.fromRecord(record, repository, true);
|
|
1808
1811
|
}
|
|
1809
1812
|
static async find(id) {
|
|
1810
|
-
const statics = modelStatics(
|
|
1811
|
-
const repository = resolveModelRepository(
|
|
1813
|
+
const statics = modelStatics(Model);
|
|
1814
|
+
const repository = resolveModelRepository(Model);
|
|
1812
1815
|
const primaryKey = repository.getTable().primaryKey;
|
|
1813
|
-
const record = await Model.query.call(
|
|
1816
|
+
const record = await Model.query.call(Model).where({ [primaryKey]: id }).first();
|
|
1814
1817
|
return record ? statics.fromRecord(record, repository, true) : null;
|
|
1815
1818
|
}
|
|
1816
1819
|
static async findOrFail(id, errorFactory) {
|
|
1817
|
-
const model = await Model.find.call(
|
|
1820
|
+
const model = await Model.find.call(Model, id);
|
|
1818
1821
|
if (model) {
|
|
1819
1822
|
return model;
|
|
1820
1823
|
}
|
|
1821
|
-
throw errorFactory?.(id) ?? new NotFoundError(`${
|
|
1824
|
+
throw errorFactory?.(id) ?? new NotFoundError(`${Model.name} ${String(id)} not found.`);
|
|
1822
1825
|
}
|
|
1823
1826
|
static async all(options = {}) {
|
|
1824
1827
|
const statics = modelStatics(this);
|
|
1825
|
-
const repository = resolveModelRepository(
|
|
1826
|
-
let query = Model.query.call(
|
|
1828
|
+
const repository = resolveModelRepository(Model);
|
|
1829
|
+
let query = Model.query.call(Model);
|
|
1827
1830
|
if (options.orderBy) {
|
|
1828
1831
|
query = query.orderBy(options.orderBy);
|
|
1829
1832
|
}
|
|
@@ -1835,8 +1838,8 @@ class Model {
|
|
|
1835
1838
|
}
|
|
1836
1839
|
static async firstWhere(where, options = {}) {
|
|
1837
1840
|
const statics = modelStatics(this);
|
|
1838
|
-
const repository = resolveModelRepository(
|
|
1839
|
-
let query = Model.query.call(
|
|
1841
|
+
const repository = resolveModelRepository(Model);
|
|
1842
|
+
let query = Model.query.call(Model).where(where);
|
|
1840
1843
|
if (options.orderBy) {
|
|
1841
1844
|
query = query.orderBy(options.orderBy);
|
|
1842
1845
|
}
|
package/dist/entries/view.js
CHANGED
|
@@ -1562,26 +1562,26 @@ class Model {
|
|
|
1562
1562
|
throw new Error(`${this.constructor.name}.primaryKey() is not implemented.`);
|
|
1563
1563
|
}
|
|
1564
1564
|
static primaryKeyField() {
|
|
1565
|
-
return resolveModelRepository(
|
|
1565
|
+
return resolveModelRepository(Model).getTable().primaryKey;
|
|
1566
1566
|
}
|
|
1567
1567
|
static hydrateAttributes(attributes) {
|
|
1568
|
-
const casts = modelStatics(
|
|
1568
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1569
1569
|
return applyCasts(attributes, casts, "hydrate");
|
|
1570
1570
|
}
|
|
1571
1571
|
static dehydrateAttributes(attributes) {
|
|
1572
|
-
const casts = modelStatics(
|
|
1572
|
+
const casts = modelStatics(Model).$casts ?? {};
|
|
1573
1573
|
return applyCasts(attributes, casts, "dehydrate");
|
|
1574
1574
|
}
|
|
1575
1575
|
static fromRecord(record, repository, exists = true) {
|
|
1576
|
-
const statics = modelStatics(
|
|
1576
|
+
const statics = modelStatics(Model);
|
|
1577
1577
|
const hydrated = statics.hydrateAttributes(record);
|
|
1578
1578
|
return new statics(hydrated, repository, exists);
|
|
1579
1579
|
}
|
|
1580
1580
|
static boot() {}
|
|
1581
1581
|
static addGlobalScope(_name, scope) {
|
|
1582
|
-
ensureBooted(
|
|
1583
|
-
const existing = modelGlobalScopes.get(
|
|
1584
|
-
modelGlobalScopes.set(
|
|
1582
|
+
ensureBooted(Model);
|
|
1583
|
+
const existing = modelGlobalScopes.get(Model) ?? [];
|
|
1584
|
+
modelGlobalScopes.set(Model, [
|
|
1585
1585
|
...existing,
|
|
1586
1586
|
scope
|
|
1587
1587
|
]);
|
|
@@ -1591,17 +1591,17 @@ class Model {
|
|
|
1591
1591
|
}
|
|
1592
1592
|
static query() {
|
|
1593
1593
|
ensureBooted(this);
|
|
1594
|
-
const repository = resolveModelRepository(
|
|
1594
|
+
const repository = resolveModelRepository(Model);
|
|
1595
1595
|
let query = repository.query();
|
|
1596
|
-
for (const scope of getGlobalScopes(
|
|
1596
|
+
for (const scope of getGlobalScopes(Model)) {
|
|
1597
1597
|
query = scope(query);
|
|
1598
1598
|
}
|
|
1599
1599
|
return query;
|
|
1600
1600
|
}
|
|
1601
1601
|
static async create(attributes) {
|
|
1602
1602
|
const statics = modelStatics(this);
|
|
1603
|
-
ensureBooted(
|
|
1604
|
-
const repository = resolveModelRepository(
|
|
1603
|
+
ensureBooted(Model);
|
|
1604
|
+
const repository = resolveModelRepository(Model);
|
|
1605
1605
|
const table = repository.getTable();
|
|
1606
1606
|
const timestamps = statics.$timestamps ?? true;
|
|
1607
1607
|
const assignable = filterMassAssignable(statics.$fillable, statics.$guarded, attributes);
|
|
@@ -1611,23 +1611,23 @@ class Model {
|
|
|
1611
1611
|
return statics.fromRecord(record, repository, true);
|
|
1612
1612
|
}
|
|
1613
1613
|
static async find(id) {
|
|
1614
|
-
const statics = modelStatics(
|
|
1615
|
-
const repository = resolveModelRepository(
|
|
1614
|
+
const statics = modelStatics(Model);
|
|
1615
|
+
const repository = resolveModelRepository(Model);
|
|
1616
1616
|
const primaryKey = repository.getTable().primaryKey;
|
|
1617
|
-
const record = await Model.query.call(
|
|
1617
|
+
const record = await Model.query.call(Model).where({ [primaryKey]: id }).first();
|
|
1618
1618
|
return record ? statics.fromRecord(record, repository, true) : null;
|
|
1619
1619
|
}
|
|
1620
1620
|
static async findOrFail(id, errorFactory) {
|
|
1621
|
-
const model = await Model.find.call(
|
|
1621
|
+
const model = await Model.find.call(Model, id);
|
|
1622
1622
|
if (model) {
|
|
1623
1623
|
return model;
|
|
1624
1624
|
}
|
|
1625
|
-
throw errorFactory?.(id) ?? new NotFoundError(`${
|
|
1625
|
+
throw errorFactory?.(id) ?? new NotFoundError(`${Model.name} ${String(id)} not found.`);
|
|
1626
1626
|
}
|
|
1627
1627
|
static async all(options = {}) {
|
|
1628
1628
|
const statics = modelStatics(this);
|
|
1629
|
-
const repository = resolveModelRepository(
|
|
1630
|
-
let query = Model.query.call(
|
|
1629
|
+
const repository = resolveModelRepository(Model);
|
|
1630
|
+
let query = Model.query.call(Model);
|
|
1631
1631
|
if (options.orderBy) {
|
|
1632
1632
|
query = query.orderBy(options.orderBy);
|
|
1633
1633
|
}
|
|
@@ -1639,8 +1639,8 @@ class Model {
|
|
|
1639
1639
|
}
|
|
1640
1640
|
static async firstWhere(where, options = {}) {
|
|
1641
1641
|
const statics = modelStatics(this);
|
|
1642
|
-
const repository = resolveModelRepository(
|
|
1643
|
-
let query = Model.query.call(
|
|
1642
|
+
const repository = resolveModelRepository(Model);
|
|
1643
|
+
let query = Model.query.call(Model).where(where);
|
|
1644
1644
|
if (options.orderBy) {
|
|
1645
1645
|
query = query.orderBy(options.orderBy);
|
|
1646
1646
|
}
|
|
@@ -2802,76 +2802,64 @@ function hashApiToken(token) {
|
|
|
2802
2802
|
var tokenServiceToken = CORE_TOKEN_SERVICE_TOKEN;
|
|
2803
2803
|
|
|
2804
2804
|
// ../../src/core/http/csrfToken.ts
|
|
2805
|
-
import {
|
|
2805
|
+
import { timingSafeEqual } from "crypto";
|
|
2806
|
+
|
|
2807
|
+
// ../../src/core/http/cookies.ts
|
|
2808
|
+
function readRequestCookie(request, name) {
|
|
2809
|
+
const cookies = request.cookies;
|
|
2810
|
+
if (cookies && typeof cookies.get === "function") {
|
|
2811
|
+
const value = cookies.get(name);
|
|
2812
|
+
if (value) {
|
|
2813
|
+
return value;
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
const header = request.headers.get("cookie");
|
|
2817
|
+
if (!header) {
|
|
2818
|
+
return null;
|
|
2819
|
+
}
|
|
2820
|
+
for (const part of header.split(";")) {
|
|
2821
|
+
const idx = part.indexOf("=");
|
|
2822
|
+
if (idx === -1)
|
|
2823
|
+
continue;
|
|
2824
|
+
const cookieName = part.slice(0, idx).trim();
|
|
2825
|
+
if (cookieName !== name)
|
|
2826
|
+
continue;
|
|
2827
|
+
return decodeURIComponent(part.slice(idx + 1).trim());
|
|
2828
|
+
}
|
|
2829
|
+
return null;
|
|
2830
|
+
}
|
|
2831
|
+
function readBunRequestCookie(request, name) {
|
|
2832
|
+
return request.cookies.get(name) ?? readRequestCookie(request, name);
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
// ../../src/core/http/csrfToken.ts
|
|
2806
2836
|
var CSRF_COOKIE = "workhub_csrf";
|
|
2807
2837
|
var CSRF_TTL_MS = 60 * 60 * 1000;
|
|
2808
2838
|
function resolveCsrfSecret() {
|
|
2809
2839
|
return process.env.SESSION_SECRET?.trim() || process.env.OAUTH_STATE_SECRET?.trim() || process.env.ADMIN_API_TOKEN?.trim() || "workhub-dev-csrf-secret";
|
|
2810
2840
|
}
|
|
2811
|
-
function
|
|
2812
|
-
|
|
2813
|
-
const signature = createHmac4("sha256", resolveCsrfSecret()).update(payload).digest("hex");
|
|
2814
|
-
return `${payload}.${signature}`;
|
|
2841
|
+
function csrfVerifyOptions() {
|
|
2842
|
+
return { secret: resolveCsrfSecret(), maxAge: CSRF_TTL_MS };
|
|
2815
2843
|
}
|
|
2816
|
-
function
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
for (const part of cookieHeader.split(";")) {
|
|
2822
|
-
const [name, ...rest] = part.trim().split("=");
|
|
2823
|
-
if (name === CSRF_COOKIE) {
|
|
2824
|
-
return decodeURIComponent(rest.join("="));
|
|
2825
|
-
}
|
|
2826
|
-
}
|
|
2827
|
-
return null;
|
|
2828
|
-
}
|
|
2829
|
-
function parseSignedCsrfValue(cookieValue) {
|
|
2830
|
-
const parts = cookieValue.split(".");
|
|
2831
|
-
if (parts.length !== 3) {
|
|
2832
|
-
return null;
|
|
2833
|
-
}
|
|
2834
|
-
const [token, issuedAtRaw, cookieSignature] = parts;
|
|
2835
|
-
if (!token || !issuedAtRaw || !cookieSignature) {
|
|
2836
|
-
return null;
|
|
2837
|
-
}
|
|
2838
|
-
const issuedAt = Number.parseInt(issuedAtRaw, 10);
|
|
2839
|
-
if (!Number.isFinite(issuedAt)) {
|
|
2840
|
-
return null;
|
|
2841
|
-
}
|
|
2842
|
-
if (Date.now() - issuedAt > CSRF_TTL_MS) {
|
|
2843
|
-
return null;
|
|
2844
|
-
}
|
|
2845
|
-
const expectedSignature = signCsrfToken(token, issuedAt).split(".").pop();
|
|
2846
|
-
if (!expectedSignature) {
|
|
2847
|
-
return null;
|
|
2848
|
-
}
|
|
2849
|
-
const expectedBuffer = Buffer.from(expectedSignature);
|
|
2850
|
-
const actualBuffer = Buffer.from(cookieSignature);
|
|
2851
|
-
if (expectedBuffer.length !== actualBuffer.length) {
|
|
2852
|
-
return null;
|
|
2853
|
-
}
|
|
2854
|
-
if (!timingSafeEqual(expectedBuffer, actualBuffer)) {
|
|
2855
|
-
return null;
|
|
2844
|
+
function tokensMatch(left, right) {
|
|
2845
|
+
const leftBuffer = Buffer.from(left);
|
|
2846
|
+
const rightBuffer = Buffer.from(right);
|
|
2847
|
+
if (leftBuffer.length !== rightBuffer.length) {
|
|
2848
|
+
return false;
|
|
2856
2849
|
}
|
|
2857
|
-
return
|
|
2850
|
+
return timingSafeEqual(leftBuffer, rightBuffer);
|
|
2858
2851
|
}
|
|
2859
2852
|
function createCsrfTokenCookie() {
|
|
2860
|
-
const token =
|
|
2861
|
-
const issuedAt = Date.now();
|
|
2862
|
-
const value = signCsrfToken(token, issuedAt);
|
|
2853
|
+
const token = Bun.CSRF.generate(resolveCsrfSecret(), { expiresIn: CSRF_TTL_MS });
|
|
2863
2854
|
return {
|
|
2864
2855
|
token,
|
|
2865
|
-
cookie: `${CSRF_COOKIE}=${encodeURIComponent(
|
|
2856
|
+
cookie: `${CSRF_COOKIE}=${encodeURIComponent(token)}; Path=/; SameSite=Lax; Max-Age=${Math.floor(CSRF_TTL_MS / 1000)}`
|
|
2866
2857
|
};
|
|
2867
2858
|
}
|
|
2868
2859
|
function resolveCsrfToken(request) {
|
|
2869
|
-
const cookieValue =
|
|
2870
|
-
if (cookieValue) {
|
|
2871
|
-
|
|
2872
|
-
if (parsed) {
|
|
2873
|
-
return { token: parsed.token };
|
|
2874
|
-
}
|
|
2860
|
+
const cookieValue = readRequestCookie(request, CSRF_COOKIE);
|
|
2861
|
+
if (cookieValue && Bun.CSRF.verify(cookieValue, csrfVerifyOptions())) {
|
|
2862
|
+
return { token: cookieValue };
|
|
2875
2863
|
}
|
|
2876
2864
|
return createCsrfTokenCookie();
|
|
2877
2865
|
}
|
|
@@ -2894,6 +2882,10 @@ async function readSubmittedCsrfTokenFromBody(request) {
|
|
|
2894
2882
|
if (typeof field === "string" && field.trim().length > 0) {
|
|
2895
2883
|
return field.trim();
|
|
2896
2884
|
}
|
|
2885
|
+
const legacyField = formData.get("_csrf");
|
|
2886
|
+
if (typeof legacyField === "string" && legacyField.trim().length > 0) {
|
|
2887
|
+
return legacyField.trim();
|
|
2888
|
+
}
|
|
2897
2889
|
}
|
|
2898
2890
|
return null;
|
|
2899
2891
|
}
|
|
@@ -2901,20 +2893,14 @@ function verifyCsrfToken(request, submittedToken) {
|
|
|
2901
2893
|
if (!submittedToken) {
|
|
2902
2894
|
return false;
|
|
2903
2895
|
}
|
|
2904
|
-
const cookieValue =
|
|
2896
|
+
const cookieValue = readRequestCookie(request, CSRF_COOKIE);
|
|
2905
2897
|
if (!cookieValue) {
|
|
2906
2898
|
return false;
|
|
2907
2899
|
}
|
|
2908
|
-
|
|
2909
|
-
if (!parsed) {
|
|
2910
|
-
return false;
|
|
2911
|
-
}
|
|
2912
|
-
const submittedBuffer = Buffer.from(submittedToken);
|
|
2913
|
-
const expectedBuffer = Buffer.from(parsed.token);
|
|
2914
|
-
if (submittedBuffer.length !== expectedBuffer.length) {
|
|
2900
|
+
if (!tokensMatch(submittedToken, cookieValue)) {
|
|
2915
2901
|
return false;
|
|
2916
2902
|
}
|
|
2917
|
-
return
|
|
2903
|
+
return Bun.CSRF.verify(submittedToken, csrfVerifyOptions());
|
|
2918
2904
|
}
|
|
2919
2905
|
function resolveCsrfTokenForRequest(request) {
|
|
2920
2906
|
const metaToken = currentRequestMeta().csrfToken;
|
|
@@ -2925,14 +2911,14 @@ function resolveCsrfTokenForRequest(request) {
|
|
|
2925
2911
|
}
|
|
2926
2912
|
|
|
2927
2913
|
// ../../src/core/http/flashSession.ts
|
|
2928
|
-
import { createHmac as
|
|
2914
|
+
import { createHmac as createHmac4, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
2929
2915
|
var FLASH_COOKIE = "workhub_flash";
|
|
2930
2916
|
var FLASH_TTL_MS = 60 * 1000;
|
|
2931
2917
|
function resolveFlashSecret() {
|
|
2932
2918
|
return process.env.SESSION_SECRET?.trim() || process.env.OAUTH_STATE_SECRET?.trim() || "workhub-dev-flash-secret";
|
|
2933
2919
|
}
|
|
2934
2920
|
function signFlashPayload(payload, issuedAt) {
|
|
2935
|
-
const signature =
|
|
2921
|
+
const signature = createHmac4("sha256", resolveFlashSecret()).update(`${payload}.${issuedAt}`).digest("hex");
|
|
2936
2922
|
return `${payload}.${issuedAt}.${signature}`;
|
|
2937
2923
|
}
|
|
2938
2924
|
function readFlashCookie(request) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Stable framework surface for application modules and future package extraction.
|
|
3
3
|
* Import from `@getstrata/core` (workspace) or `src/framework/public-api`.
|
|
4
4
|
*/
|
|
5
|
+
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../bootstrap/applicationRegistry.ts";
|
|
5
6
|
export type { ServiceProvider } from "../bootstrap/contracts.ts";
|
|
6
7
|
export { ConfigStore, resolveService, ServiceContainer, } from "../bootstrap/contracts.ts";
|
|
7
8
|
export type { AbilityChecker } from "../core/auth/abilityChecker.ts";
|
|
@@ -13,6 +14,7 @@ export { CACHE_TAGS } from "../core/cache/tags.ts";
|
|
|
13
14
|
export type { DatabaseConnection } from "../core/database/baseRepository.ts";
|
|
14
15
|
export { default as BaseRepository } from "../core/database/baseRepository.ts";
|
|
15
16
|
export { bindDatabaseConnection } from "../core/database/bindConnection.ts";
|
|
17
|
+
export { createDatabaseConnection } from "../core/database/connection.ts";
|
|
16
18
|
export { getActiveDatabaseConnection, runWithDatabaseConnection, } from "../core/database/connectionContext.ts";
|
|
17
19
|
export { withMigrationLock } from "../core/database/migrations/advisoryLock.ts";
|
|
18
20
|
export { freshDatabase, getMigrationStatus, loadMigrationsFromDirectory, migrateDatabase, rollbackDatabase, } from "../core/database/migrations/runner.ts";
|
|
@@ -35,7 +37,10 @@ export { BadRequestError, ConflictError, ForbiddenError, NotFoundError, Precondi
|
|
|
35
37
|
export { EventBus } from "../core/events/eventBus.ts";
|
|
36
38
|
export { auth, cache, config, events, log, mail, policyGate, queue, storage, } from "../core/facades/index.ts";
|
|
37
39
|
export { createBodySizeLimitMiddleware } from "../core/http/bodySizeLimitMiddleware.ts";
|
|
40
|
+
export { readBunRequestCookie, readRequestCookie } from "../core/http/cookies.ts";
|
|
38
41
|
export { createCsrfMiddleware } from "../core/http/csrfMiddleware.ts";
|
|
42
|
+
export { createCsrfProtection } from "../core/http/csrfProtection.ts";
|
|
43
|
+
export { createCsrfTokenCookie, readSubmittedCsrfToken, readSubmittedCsrfTokenFromBody, resolveCsrfToken, resolveCsrfTokenForRequest, verifyCsrfToken, } from "../core/http/csrfToken.ts";
|
|
39
44
|
export { assertIfMatch, etagFromResource, isEtagEnabled, } from "../core/http/etag.ts";
|
|
40
45
|
export { FormRequest } from "../core/http/formRequest.ts";
|
|
41
46
|
export { applyMiddlewareToRoutes, composeMiddleware, createAuthMiddleware, createAuthorizeMiddleware, createdResponse, createRequireAuthMiddleware, jsonResponse, noContentResponse, paginatedResponse, parsePaginationQuery, securedBindRouteModel, securedBindRouteModelByKey, withErrorHandling, withMiddleware, } from "../core/http/index.ts";
|