@rytass/bpm-core-nestjs-module 0.12.0 → 0.13.1
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/CHANGELOG.md +46 -0
- package/README.md +160 -3
- package/package.json +3 -3
- package/src/lib/attachment/attachment-options.d.ts +11 -0
- package/src/lib/attachment/attachment-options.js +21 -6
- package/src/lib/attachment/attachment-options.js.map +1 -1
- package/src/lib/attachment/index.d.ts +1 -0
- package/src/lib/attachment/index.js +1 -0
- package/src/lib/attachment/index.js.map +1 -1
- package/src/lib/bpm/bpm-root.module.d.ts +35 -0
- package/src/lib/bpm/bpm-root.module.js +8 -0
- package/src/lib/bpm/bpm-root.module.js.map +1 -1
- package/src/lib/bpm-auth/bpm-auth.authorization.js +3 -2
- package/src/lib/bpm-auth/bpm-auth.authorization.js.map +1 -1
- package/src/lib/bpm-auth/bpm-auth.decorators.js +2 -1
- package/src/lib/bpm-auth/bpm-auth.decorators.js.map +1 -1
- package/src/lib/bpm-auth/bpm-resolver-access.decorator.d.ts +13 -0
- package/src/lib/bpm-auth/bpm-resolver-access.decorator.js +27 -0
- package/src/lib/bpm-auth/bpm-resolver-access.decorator.js.map +1 -0
- package/src/lib/bpm-auth/bpm-resolver-metadata.d.ts +73 -0
- package/src/lib/bpm-auth/bpm-resolver-metadata.js +158 -0
- package/src/lib/bpm-auth/bpm-resolver-metadata.js.map +1 -0
- package/src/lib/bpm-auth/index.d.ts +2 -0
- package/src/lib/bpm-auth/index.js +2 -0
- package/src/lib/bpm-auth/index.js.map +1 -1
- package/src/lib/condition/condition.service.js +45 -4
- package/src/lib/condition/condition.service.js.map +1 -1
- package/src/lib/identity/identity-options.d.ts +16 -0
- package/src/lib/identity/identity-options.js.map +1 -1
- package/src/lib/identity/identity.module.d.ts +6 -0
- package/src/lib/identity/identity.module.js +9 -2
- package/src/lib/identity/identity.module.js.map +1 -1
- package/src/lib/migrations/0000000000001-enable-postgres-extensions.d.ts +9 -1
- package/src/lib/migrations/0000000000001-enable-postgres-extensions.js +55 -4
- package/src/lib/migrations/0000000000001-enable-postgres-extensions.js.map +1 -1
- package/src/lib/notification/index.d.ts +1 -0
- package/src/lib/notification/index.js +1 -0
- package/src/lib/notification/index.js.map +1 -1
- package/src/lib/organization/dto/manager-resolution.input.d.ts +7 -7
- package/src/lib/organization/dto/membership.input.d.ts +7 -7
- package/src/lib/organization/dto/org-unit.input.d.ts +28 -6
- package/src/lib/organization/dto/org-unit.input.js +4 -2
- package/src/lib/organization/dto/org-unit.input.js.map +1 -1
- package/src/lib/organization/dto/position.input.d.ts +4 -4
- package/src/lib/organization/index.d.ts +4 -0
- package/src/lib/organization/index.js +4 -0
- package/src/lib/organization/index.js.map +1 -1
- package/src/lib/organization/organization.mutations.d.ts +1 -0
- package/src/lib/organization/organization.mutations.js +10 -0
- package/src/lib/organization/organization.mutations.js.map +1 -1
- package/src/lib/organization/organization.service.d.ts +43 -0
- package/src/lib/organization/organization.service.js +166 -7
- package/src/lib/organization/organization.service.js.map +1 -1
- package/src/lib/template/dto/approval-template.input.d.ts +31 -20
- package/src/lib/template/dto/approval-template.input.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
## 0.13.1 (2026-09-04)
|
|
2
|
+
|
|
3
|
+
### 🩹 Fixes
|
|
4
|
+
|
|
5
|
+
- **release:** build before publishing, and follow the 0.x bump convention ([a41932a](https://github.com/Rytass/BPMCore/commit/a41932a))
|
|
6
|
+
|
|
7
|
+
### ❤️ Thank You
|
|
8
|
+
|
|
9
|
+
- Chia Yu Pai @fantasywind
|
|
10
|
+
- Claude Opus 5
|
|
11
|
+
|
|
12
|
+
## 0.13.0 (2026-09-03)
|
|
13
|
+
|
|
14
|
+
### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- **bpm-auth:** let a host stamp its own route metadata on BPM resolvers ([49bedb7](https://github.com/Rytass/BPMCore/commit/49bedb7))
|
|
17
|
+
- **identity:** let a host turn off the identity GraphQL queries ([33630f8](https://github.com/Rytass/BPMCore/commit/33630f8))
|
|
18
|
+
|
|
19
|
+
### 🩹 Fixes
|
|
20
|
+
|
|
21
|
+
- **migrations:** stop dropping extensions this migration may not have created ([88256d1](https://github.com/Rytass/BPMCore/commit/88256d1))
|
|
22
|
+
- **condition:** name the Node version when cel-js cannot be required ([2691e63](https://github.com/Rytass/BPMCore/commit/2691e63))
|
|
23
|
+
- **bpm-auth:** list only real GraphQL handlers, and keep symbol metadata keys ([9cc4593](https://github.com/Rytass/BPMCore/commit/9cc4593))
|
|
24
|
+
- ⚠️ **attachment:** refuse to sign production attachment URLs with the public dev key ([c40ce67](https://github.com/Rytass/BPMCore/commit/c40ce67))
|
|
25
|
+
- **migrations:** explain what to do when CREATE EXTENSION is denied ([a0c9c38](https://github.com/Rytass/BPMCore/commit/a0c9c38))
|
|
26
|
+
- **condition:** load cel-js on first use, not on import ([e2a64c9](https://github.com/Rytass/BPMCore/commit/e2a64c9))
|
|
27
|
+
- **template:** let UpdateApprovalTemplateInput say "keep the category" ([c11c248](https://github.com/Rytass/BPMCore/commit/c11c248))
|
|
28
|
+
- **organization:** let update inputs say "leave this alone", and allow deleting a position ([e09e012](https://github.com/Rytass/BPMCore/commit/e09e012))
|
|
29
|
+
|
|
30
|
+
### ⚠️ Breaking Changes
|
|
31
|
+
|
|
32
|
+
- **attachment:** refuse to sign production attachment URLs with the public dev key ([c40ce67](https://github.com/Rytass/BPMCore/commit/c40ce67))
|
|
33
|
+
a NODE_ENV=production process that never set
|
|
34
|
+
attachmentSignedUrlSecret no longer starts. BPMRootModule mounts
|
|
35
|
+
AttachmentModule unconditionally, so this reaches hosts that serve no
|
|
36
|
+
attachments at all. Set the secret, or set
|
|
37
|
+
attachmentAllowInsecureSignedUrlSecret: true to acknowledge that the signing
|
|
38
|
+
key is public.
|
|
39
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
40
|
+
Claude-Session: https://claude.ai/code/session_016VKxnq3cFuySFMLMZhtd2E
|
|
41
|
+
|
|
42
|
+
### ❤️ Thank You
|
|
43
|
+
|
|
44
|
+
- Chia Yu Pai @fantasywind
|
|
45
|
+
- Claude Opus 5
|
|
46
|
+
|
|
1
47
|
## 0.12.0 (2026-08-27)
|
|
2
48
|
|
|
3
49
|
### 🚀 Features
|
package/README.md
CHANGED
|
@@ -582,6 +582,62 @@ export class BPMAuthContextFactory {
|
|
|
582
582
|
> module or a database table) so adding a new BPM tier in a future
|
|
583
583
|
> BPMCore release becomes a one-line addition.
|
|
584
584
|
|
|
585
|
+
### Coexisting with a host global guard
|
|
586
|
+
|
|
587
|
+
`APP_GUARD`-registered guards run **before** BPM's own. A guard that decides
|
|
588
|
+
by route metadata therefore judges BPM's resolvers by metadata BPM never
|
|
589
|
+
writes — and `@rytass/member-base-nestjs-module`'s `CasbinGuard` rejects any
|
|
590
|
+
route without `@CheckPermission`:
|
|
591
|
+
|
|
592
|
+
```json
|
|
593
|
+
{ "errors": [{ "message": "Route has no permission metadata",
|
|
594
|
+
"path": ["orgUnits"],
|
|
595
|
+
"extensions": { "code": "FORBIDDEN" } }] }
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Every BPM query and mutation fails this way, before BPM's guards run at all.
|
|
599
|
+
BPM cannot import the host's decorator, and a decorator cannot read module
|
|
600
|
+
options — it runs when the class is defined. So BPM's resolvers register
|
|
601
|
+
themselves, and `resolverMetadataFactory` replays your factory over them at
|
|
602
|
+
module wiring time:
|
|
603
|
+
|
|
604
|
+
```ts
|
|
605
|
+
import { PERMISSION_METADATA_KEY } from '@rytass/member-base-nestjs-module';
|
|
606
|
+
import { BPMRootModule, type BPMResolverMetadataFactory } from '@rytass/bpm-core-nestjs-module';
|
|
607
|
+
|
|
608
|
+
const HOST_PERMISSIONS: Readonly<Record<string, readonly string[]>> = {
|
|
609
|
+
admin: ['bpm:admin'],
|
|
610
|
+
authenticated: ['bpm:use'],
|
|
611
|
+
designer: ['bpm:design'],
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
const resolverMetadataFactory: BPMResolverMetadataFactory = ({ access }) => ({
|
|
615
|
+
[PERMISSION_METADATA_KEY]: HOST_PERMISSIONS[access],
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
BPMRootModule.forRoot({ resolverMetadataFactory, /* ... */ });
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
The factory is called once per handler and receives `{ access, resolverName,
|
|
622
|
+
methodName }`. `access` is the authority BPM's own guards require —
|
|
623
|
+
`'admin'`, `'designer'`, or `'authenticated'` — so the common case is one
|
|
624
|
+
lookup table rather than a per-operation list. `methodName` is also the
|
|
625
|
+
GraphQL field name (`orgUnits`, `createOrgUnit`, `member`) when a handful of
|
|
626
|
+
operations need finer grants. Returning `null` leaves a handler untouched.
|
|
627
|
+
|
|
628
|
+
The returned record is written onto the prototype method, which is exactly
|
|
629
|
+
what Nest hands a guard as `context.getHandler()`; BPM's own guards still run
|
|
630
|
+
afterwards, so both permission models apply.
|
|
631
|
+
|
|
632
|
+
`listBPMResolverHandlers()` prints every handler the factory will be offered,
|
|
633
|
+
which is the quickest way to build the mapping table:
|
|
634
|
+
|
|
635
|
+
```ts
|
|
636
|
+
import { listBPMResolverHandlers } from '@rytass/bpm-core-nestjs-module';
|
|
637
|
+
|
|
638
|
+
console.table([...listBPMResolverHandlers()]);
|
|
639
|
+
```
|
|
640
|
+
|
|
585
641
|
## Member Resolver
|
|
586
642
|
|
|
587
643
|
The package resolves display names, email addresses, and approver candidates
|
|
@@ -873,6 +929,7 @@ BPMRootModule.forRootAsync({
|
|
|
873
929
|
| ------------------------------------------------ | ------------------------------ | -------------------------------------------------------------- |
|
|
874
930
|
| `authContextFactory` | `undefined` | Reads `BPMAuthContext` from NestJS `ExecutionContext`. |
|
|
875
931
|
| `memberResolverProvider` | required | Provider for `BPM_MEMBER_RESOLVER`. |
|
|
932
|
+
| `resolverMetadataFactory` | `undefined` | Stamps the host's own route metadata onto every BPM GraphQL handler. Required when the host installs a global metadata-driven guard — see "Coexisting with a host global guard". |
|
|
876
933
|
| `attachmentStorageProvider` | local `.storage/attachments` | Host-provided `@rytass/storages` adapter. |
|
|
877
934
|
| `workflowServiceTaskDispatcherProvider` | built-in `fetch` dispatcher | Host provider for executable workflow `WEBHOOK` service tasks. |
|
|
878
935
|
| `businessCalendarProvider` | Monday–Friday calendar | Host provider for `BPM_BUSINESS_CALENDAR`, used by `BUSINESS_DAY` SLAs. BPMCore ships no holiday data. |
|
|
@@ -880,9 +937,11 @@ BPMRootModule.forRootAsync({
|
|
|
880
937
|
| `attachmentRoutePrefix` | `/attachments` | Drives both the BPM signed URL path and the Nest controller mount path for `AttachmentController`. Must be set at module wiring time (see "Attachment Storage" below). |
|
|
881
938
|
| `attachmentStorageProviderId` | `local` | Value stored on attachment metadata for the active adapter. |
|
|
882
939
|
| `attachmentPublicBaseUrl` | `http://localhost:17603` | Public base URL for signed attachment URLs. |
|
|
883
|
-
| `attachmentSignedUrlSecret` | local development secret | HMAC secret for signed attachment download/preview tokens.
|
|
940
|
+
| `attachmentSignedUrlSecret` | local development secret | HMAC secret for signed attachment download/preview tokens. Under `NODE_ENV=production` BPM refuses to start while this is unset. |
|
|
941
|
+
| `attachmentAllowInsecureSignedUrlSecret` | `false` | Opt-in that lets a `NODE_ENV=production` process boot on the built-in development secret anyway. Only for throwaway environments — the value is published in this package. |
|
|
884
942
|
| `attachmentSignedUrlTtlSeconds` | `300` | Signed attachment URL lifetime in seconds. |
|
|
885
943
|
| `identityMemberMetadataCacheTtlMs` | `300000` | Member metadata cache TTL. |
|
|
944
|
+
| `identityRegisterResolvers` | `true` | Set to `false` when the host already publishes `member` / `members` / `memberCount` / `searchMembers` GraphQL queries. `IdentityService` stays available either way. |
|
|
886
945
|
| `notificationInAppEnabled` | `true` | Enables in-app notification records. |
|
|
887
946
|
| `notificationEmailEnabled` | `auto` | Enables email when SMTP settings are complete. |
|
|
888
947
|
| `notificationEmailSmtpHost` | `null` | SMTP host. |
|
|
@@ -919,8 +978,95 @@ BPMRootModule.forRootAsync({
|
|
|
919
978
|
|
|
920
979
|
Production deployments should override all local development secrets.
|
|
921
980
|
|
|
981
|
+
### Mounting a single domain module
|
|
982
|
+
|
|
983
|
+
`BPMRootModule` is the supported entry point and the only one that wires the
|
|
984
|
+
whole product. A host that wants **one** BPM domain — most often organization
|
|
985
|
+
data, with no workflow, forms, or notifications — can import that domain
|
|
986
|
+
module on its own. These are self-contained: they declare their own
|
|
987
|
+
`TypeOrmModule.forFeature` and their services inject nothing but `DataSource`
|
|
988
|
+
and repositories.
|
|
989
|
+
|
|
990
|
+
```ts
|
|
991
|
+
import { Module } from '@nestjs/common';
|
|
992
|
+
import { OrganizationModule, OrganizationService } from '@rytass/bpm-core-nestjs-module';
|
|
993
|
+
|
|
994
|
+
@Module({ imports: [OrganizationModule] })
|
|
995
|
+
export class HostOrganizationModule {}
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
| Module | Self-contained | Notes |
|
|
999
|
+
| -------------------- | -------------- | -------------------------------------------------------------------- |
|
|
1000
|
+
| `OrganizationModule` | yes | Org units, positions, memberships, manager resolution. Mounted alone, `deletePosition` silently skips its approval-template and ad-hoc-directive reference checks (it logs when it does) — those tables are not in the schema. |
|
|
1001
|
+
| `FormModule` | yes | Form definitions and versions. |
|
|
1002
|
+
| `TemplateModule` | yes | Approval templates, versions, categories. |
|
|
1003
|
+
| `ConditionModule` | yes | CEL lint and evaluation only. |
|
|
1004
|
+
| `IdentityModule` | no | Needs `memberResolverProvider`; use `IdentityModule.forRoot(...)`. |
|
|
1005
|
+
| `AttachmentModule` | no | Needs storage and signed-URL options; use `AttachmentModule.forRoot(...)`. |
|
|
1006
|
+
|
|
1007
|
+
What you still owe them:
|
|
1008
|
+
|
|
1009
|
+
- **Migrations.** `BPM_CORE_MIGRATIONS` is one list for the whole package; a
|
|
1010
|
+
single-module host still runs all of it, and still needs the extensions in
|
|
1011
|
+
"Database prerequisites" below.
|
|
1012
|
+
- **Auth.** A domain module imported directly does not bring `BPMAuthModule`,
|
|
1013
|
+
so `@BPMAdminOnly()` on its resolvers has no auth context accessor to
|
|
1014
|
+
inject. Either import `BPMAuthModule.forRoot({ contextFactory })` alongside
|
|
1015
|
+
it, or use the domain **service** and publish your own GraphQL surface.
|
|
1016
|
+
- **Resolver metadata.** `resolverMetadataFactory` is applied by
|
|
1017
|
+
`BPMRootModule`, which is not in play here. A host that needs it on this path
|
|
1018
|
+
calls `applyBPMResolverMetadata(factory)` itself, once, before the
|
|
1019
|
+
application starts.
|
|
1020
|
+
|
|
1021
|
+
The domain services (`OrganizationService` and friends) are the stable part of
|
|
1022
|
+
this arrangement; a module's internal wiring is not. If you are here because
|
|
1023
|
+
`BPMRootModule` collides with your schema, `identityRegisterResolvers` and
|
|
1024
|
+
`resolverMetadataFactory` usually let you keep the supported entry point.
|
|
1025
|
+
|
|
1026
|
+
### Testing a host that depends on BPM
|
|
1027
|
+
|
|
1028
|
+
BPM loads `cel-js` — ESM-only, with a `chevrotain` dependency whose exports
|
|
1029
|
+
map `jest-resolve` cannot follow — lazily, on the first CEL expression it
|
|
1030
|
+
parses. Importing anything from the package root does not reach it, so a host
|
|
1031
|
+
jest suite needs no `moduleNameMapper` entry and no stub.
|
|
1032
|
+
|
|
1033
|
+
A suite that *does* exercise conditions (template validation, workflow
|
|
1034
|
+
transitions) will load `cel-js` for real. If your jest version cannot resolve
|
|
1035
|
+
it, map it to a stub of your own:
|
|
1036
|
+
|
|
1037
|
+
```ts
|
|
1038
|
+
// jest.config.ts
|
|
1039
|
+
moduleNameMapper: { '^cel-js$': '<rootDir>/test/cel-js.stub.ts' },
|
|
1040
|
+
```
|
|
1041
|
+
|
|
922
1042
|
## Database Setup
|
|
923
1043
|
|
|
1044
|
+
### Database prerequisites
|
|
1045
|
+
|
|
1046
|
+
BPM's first migration enables two PostgreSQL extensions — `uuid-ossp` for
|
|
1047
|
+
`uuid_generate_v4()` defaults and `ltree` for the org unit `path` column:
|
|
1048
|
+
|
|
1049
|
+
```sql
|
|
1050
|
+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
1051
|
+
CREATE EXTENSION IF NOT EXISTS "ltree";
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
`CREATE EXTENSION` needs the CREATE privilege **on the database**, which a
|
|
1055
|
+
least-privilege application role normally does not have — including on Rytass
|
|
1056
|
+
platforms, where that privilege is revoked by convention. Have a superuser,
|
|
1057
|
+
the database owner, or `rds_superuser` run the two statements once before the
|
|
1058
|
+
first migration run.
|
|
1059
|
+
|
|
1060
|
+
PostgreSQL itself returns early from `CREATE EXTENSION IF NOT EXISTS` when the
|
|
1061
|
+
extension is present, so a least-privilege role runs migrations fine once a DBA
|
|
1062
|
+
has installed them. What the migration adds is the other case: when they are
|
|
1063
|
+
missing and the role cannot create them, it stops with the SQL above and who
|
|
1064
|
+
needs to run it, rather than a bare `42501` that says nothing about needing a
|
|
1065
|
+
DBA.
|
|
1066
|
+
|
|
1067
|
+
The migration's `down()` is deliberately a no-op — the extensions may predate
|
|
1068
|
+
BPM and other schemas in the same database may depend on them.
|
|
1069
|
+
|
|
924
1070
|
The package exports helpers for Vault-backed TypeORM setup:
|
|
925
1071
|
|
|
926
1072
|
```ts
|
|
@@ -1521,14 +1667,25 @@ npm publish --access public
|
|
|
1521
1667
|
|
|
1522
1668
|
## Production Notes
|
|
1523
1669
|
|
|
1524
|
-
- Replace all local fallback secrets before
|
|
1670
|
+
- **BREAKING (upgrade note).** Replace all local fallback secrets before
|
|
1671
|
+
production. Under `NODE_ENV=production`, `attachmentSignedUrlSecret` is now
|
|
1672
|
+
enforced: BPM refuses to start rather than sign attachment URLs with the
|
|
1673
|
+
value published in this package. `BPMRootModule` mounts `AttachmentModule`
|
|
1674
|
+
unconditionally, so this applies **even to a host that never serves
|
|
1675
|
+
attachments** — an existing production deployment that never set the secret
|
|
1676
|
+
will fail to boot after upgrading. Set the secret, or set
|
|
1677
|
+
`attachmentAllowInsecureSignedUrlSecret: true` to acknowledge that the
|
|
1678
|
+
signing key is public and boot anyway. Never set that flag on anything
|
|
1679
|
+
serving real attachments.
|
|
1525
1680
|
- Use a production storage adapter instead of local filesystem storage.
|
|
1526
1681
|
- Keep old signature keys available for verification after key rotation.
|
|
1527
1682
|
- Keep in-process schedulers disabled in API replicas unless a dedicated worker
|
|
1528
1683
|
is not available.
|
|
1529
1684
|
- Do not enable TypeORM `synchronize` in production.
|
|
1530
1685
|
- Ensure GraphQL auth context is available for protected operations.
|
|
1531
|
-
- Run migrations before serving traffic with a new package version
|
|
1686
|
+
- Run migrations before serving traffic with a new package version, and
|
|
1687
|
+
install the PostgreSQL extensions listed under "Database prerequisites"
|
|
1688
|
+
once, with a privileged role, before the first run.
|
|
1532
1689
|
|
|
1533
1690
|
## License
|
|
1534
1691
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rytass/bpm-core-nestjs-module",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Embeddable NestJS BPM approval workflow module: workflow engine, approval templates, forms, organization/member contracts, attachments, signatures, notifications, delegation, and TypeORM migrations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bpm",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
|
-
"node": ">=20.
|
|
32
|
+
"node": ">=20.19.0"
|
|
33
33
|
},
|
|
34
34
|
"type": "commonjs",
|
|
35
35
|
"main": "./src/index.js",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"@nestjs/core": ">=10.0.0",
|
|
156
156
|
"@nestjs/graphql": ">=12.0.0",
|
|
157
157
|
"@nestjs/typeorm": ">=10.0.0",
|
|
158
|
-
"@rytass/bpm-core-shared": "^0.
|
|
158
|
+
"@rytass/bpm-core-shared": "^0.13.1",
|
|
159
159
|
"@rytass/secret-adapter-vault-nestjs": ">=0.4.5",
|
|
160
160
|
"express": ">=4.0.0",
|
|
161
161
|
"graphql": ">=16.0.0",
|
|
@@ -12,6 +12,17 @@ export interface BPMRootAttachmentOptions {
|
|
|
12
12
|
* signed attachment URLs. Defaults to `/attachments`.
|
|
13
13
|
*/
|
|
14
14
|
readonly attachmentRoutePrefix?: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Opt-in escape hatch that lets a `NODE_ENV=production` process boot while
|
|
17
|
+
* still signing attachment URLs with the built-in development secret.
|
|
18
|
+
*
|
|
19
|
+
* Without it, a production process that never set
|
|
20
|
+
* `attachmentSignedUrlSecret` refuses to start. Set this only for a
|
|
21
|
+
* throwaway environment that happens to run with `NODE_ENV=production` and
|
|
22
|
+
* serves no real attachments — the built-in value is published in this
|
|
23
|
+
* package, so anyone can forge a signed attachment URL against it.
|
|
24
|
+
*/
|
|
25
|
+
readonly attachmentAllowInsecureSignedUrlSecret?: boolean;
|
|
15
26
|
/**
|
|
16
27
|
* HMAC secret used to sign attachment download and preview tokens.
|
|
17
28
|
*/
|
|
@@ -14,12 +14,27 @@ exports.DEFAULT_BPM_ATTACHMENT_OPTIONS = {
|
|
|
14
14
|
function resolveBPMAttachmentOptions(options = {}) {
|
|
15
15
|
const resolvedSignedUrlSecret = normalizeText(options.attachmentSignedUrlSecret) ??
|
|
16
16
|
exports.DEFAULT_BPM_ATTACHMENT_OPTIONS.signedUrlSecret;
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
// signed attachment
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
|
|
17
|
+
const usesBuiltInSecret = resolvedSignedUrlSecret === exports.DEFAULT_BPM_ATTACHMENT_OPTIONS.signedUrlSecret;
|
|
18
|
+
// A console warning is the wrong instrument for a published constant that
|
|
19
|
+
// makes every signed attachment URL forgeable: in a container it scrolls past
|
|
20
|
+
// with the boot log and nobody reads it again. Under `NODE_ENV=production`
|
|
21
|
+
// the process refuses to start instead, and a host that genuinely wants the
|
|
22
|
+
// development value there has to say so.
|
|
23
|
+
if (usesBuiltInSecret &&
|
|
24
|
+
process.env.NODE_ENV === 'production' &&
|
|
25
|
+
options.attachmentAllowInsecureSignedUrlSecret !== true) {
|
|
26
|
+
throw new Error([
|
|
27
|
+
'[@rytass/bpm-core-nestjs-module] attachmentSignedUrlSecret is unset, so BPM would sign attachment URLs with the built-in local development value that ships in this package — anyone could forge one.',
|
|
28
|
+
'Set BPMRootModuleOptions.attachmentSignedUrlSecret to a strong secret.',
|
|
29
|
+
'If this service never serves attachments, BPM still mounts AttachmentModule, so set attachmentAllowInsecureSignedUrlSecret: true to acknowledge that the signing key is public and boot anyway.',
|
|
30
|
+
].join(' '));
|
|
31
|
+
}
|
|
32
|
+
// Outside production, still warn everywhere except an explicit local
|
|
33
|
+
// development run. Gating the warning on production alone meant a staging
|
|
34
|
+
// host that never set the variable signed attachment URLs with the published
|
|
35
|
+
// constant — and said nothing about it. One extra line in a developer's
|
|
36
|
+
// console is the cheaper trade.
|
|
37
|
+
if (usesBuiltInSecret &&
|
|
23
38
|
process.env.NODE_ENV !== 'development' &&
|
|
24
39
|
process.env.NODE_ENV !== 'test') {
|
|
25
40
|
// eslint-disable-next-line no-console
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-options.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/attachment/attachment-options.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"attachment-options.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/attachment/attachment-options.ts"],"names":[],"mappings":";;;AAgEA,kEAyDC;AAQD,0EAMC;AAlFY,QAAA,sBAAsB,GACjC,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAEtB,QAAA,8BAA8B,GAAiC;IAC1E,aAAa,EAAE,wBAAwB;IACvC,WAAW,EAAE,cAAc;IAC3B,eAAe,EAAE,sCAAsC;IACvD,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,OAAO;CAC3B,CAAC;AAEF,SAAgB,2BAA2B,CACzC,UAAoC,EAAE;IAEtC,MAAM,uBAAuB,GAC3B,aAAa,CAAC,OAAO,CAAC,yBAAyB,CAAC;QAChD,sCAA8B,CAAC,eAAe,CAAC;IAEjD,MAAM,iBAAiB,GACrB,uBAAuB,KAAK,sCAA8B,CAAC,eAAe,CAAC;IAE7E,0EAA0E;IAC1E,8EAA8E;IAC9E,2EAA2E;IAC3E,4EAA4E;IAC5E,yCAAyC;IACzC,IACE,iBAAiB;QACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QACrC,OAAO,CAAC,sCAAsC,KAAK,IAAI,EACvD,CAAC;QACD,MAAM,IAAI,KAAK,CACb;YACE,uMAAuM;YACvM,wEAAwE;YACxE,iMAAiM;SAClM,CAAC,IAAI,CAAC,GAAG,CAAC,CACZ,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,0EAA0E;IAC1E,6EAA6E;IAC7E,wEAAwE;IACxE,gCAAgC;IAChC,IACE,iBAAiB;QACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;QACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAC/B,CAAC;QACD,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACV,0QAA0Q,CAC3Q,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EAAE,sBAAsB,CAAC,OAAO,CAAC,uBAAuB,CAAC;QACtE,WAAW,EAAE,oBAAoB,CAAC,OAAO,CAAC,qBAAqB,CAAC;QAChE,eAAe,EAAE,uBAAuB;QACxC,mBAAmB,EAAE,wBAAwB,CAC3C,OAAO,CAAC,6BAA6B,EACrC,sCAA8B,CAAC,mBAAmB,CACnD;QACD,iBAAiB,EACf,aAAa,CAAC,OAAO,CAAC,2BAA2B,CAAC;YAClD,sCAA8B,CAAC,iBAAiB;KACnD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,+BAA+B,CAC7C,KAAgC;IAEhC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAErD,OAAO,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAgC;IAC9D,MAAM,eAAe,GACnB,aAAa,CAAC,KAAK,CAAC,IAAI,sCAA8B,CAAC,aAAa,CAAC;IAEvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC;IAC5D,MAAM,eAAe,GACnB,aAAa,CAAC,KAAK,CAAC,IAAI,sCAA8B,CAAC,WAAW,CAAC;IACrE,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC;QACtD,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC;IAE1B,OAAO,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,KAAgC;IACrD,MAAM,YAAY,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEzC,OAAO,YAAY,IAAI,IAAI,CAAC;AAC9B,CAAC;AAED,SAAS,wBAAwB,CAC/B,KAAyB,EACzB,QAAgB;IAEhB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -6,4 +6,5 @@ tslib_1.__exportStar(require("./attachment-storage.provider"), exports);
|
|
|
6
6
|
tslib_1.__exportStar(require("./attachment-storage.token"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./attachment.module"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./attachment.service"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./dto/upload-attachment.input"), exports);
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/attachment/index.ts"],"names":[],"mappings":";;;AAAA,+DAAqC;AACrC,wEAA8C;AAC9C,qEAA2C;AAC3C,8DAAoC;AACpC,+DAAqC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/attachment/index.ts"],"names":[],"mappings":";;;AAAA,+DAAqC;AACrC,wEAA8C;AAC9C,qEAA2C;AAC3C,8DAAoC;AACpC,+DAAqC;AACrC,wEAA8C"}
|
|
@@ -2,6 +2,7 @@ import { DynamicModule, InjectionToken, Provider } from '@nestjs/common';
|
|
|
2
2
|
import { ModuleMetadata } from '@nestjs/common/interfaces';
|
|
3
3
|
import { BPMRootAttachmentOptions } from '../attachment/attachment-options';
|
|
4
4
|
import { AttachmentStorage } from '../attachment/attachment-storage.token';
|
|
5
|
+
import { BPMResolverMetadataFactory } from '../bpm-auth/bpm-resolver-metadata';
|
|
5
6
|
import { BPMAuthModuleOptions } from '../bpm-auth/bpm-auth.options';
|
|
6
7
|
import { BPMBusinessCalendar } from '../calendar/business-calendar.token';
|
|
7
8
|
import { BPMFormDataSourceRegistry } from '../form-data-source';
|
|
@@ -61,6 +62,22 @@ export interface BPMRootModuleOptions extends Pick<ModuleMetadata, 'imports'>, B
|
|
|
61
62
|
* `@rytass/bpm-core-nestjs-module` to a specific external identity system.
|
|
62
63
|
*/
|
|
63
64
|
readonly memberResolverProvider: Provider<BPMMemberResolver>;
|
|
65
|
+
/**
|
|
66
|
+
* Host-supplied factory that stamps the host's own route metadata onto every
|
|
67
|
+
* BPM GraphQL handler.
|
|
68
|
+
*
|
|
69
|
+
* Needed when the host installs a **global** guard that judges routes by
|
|
70
|
+
* metadata BPM knows nothing about. `@rytass/member-base-nestjs-module`
|
|
71
|
+
* registers a `CasbinGuard` that rejects any route without
|
|
72
|
+
* `@CheckPermission` metadata, so without this every BPM query and mutation
|
|
73
|
+
* fails with `Route has no permission metadata` before BPM's own guards run.
|
|
74
|
+
*
|
|
75
|
+
* The factory is called once per handler at module wiring time, receives the
|
|
76
|
+
* authority BPM itself requires (`admin`, `designer`, `authenticated`) plus
|
|
77
|
+
* the resolver and method names, and returns the metadata to write. See
|
|
78
|
+
* `BPMResolverMetadataFactory`.
|
|
79
|
+
*/
|
|
80
|
+
readonly resolverMetadataFactory?: BPMResolverMetadataFactory;
|
|
64
81
|
/**
|
|
65
82
|
* Host-provided dispatcher for executable workflow service tasks.
|
|
66
83
|
*
|
|
@@ -116,6 +133,15 @@ export interface BPMRootModuleAsyncOptions extends Pick<ModuleMetadata, 'imports
|
|
|
116
133
|
* through its Nest `useFactory`, `useClass`, or `useExisting` definition.
|
|
117
134
|
*/
|
|
118
135
|
readonly formDataSourceRegistryProvider?: Provider<BPMFormDataSourceRegistry>;
|
|
136
|
+
/**
|
|
137
|
+
* Whether BPM registers its identity GraphQL queries. See
|
|
138
|
+
* `BPMRootIdentityOptions.identityRegisterResolvers`.
|
|
139
|
+
*
|
|
140
|
+
* Set at module wiring time, like `attachmentRoutePrefix`, because Nest
|
|
141
|
+
* collects resolver providers while building the schema — before the
|
|
142
|
+
* `useFactory` below has run.
|
|
143
|
+
*/
|
|
144
|
+
readonly identityRegisterResolvers?: boolean;
|
|
119
145
|
/**
|
|
120
146
|
* Providers injected into `useFactory`.
|
|
121
147
|
*
|
|
@@ -131,6 +157,15 @@ export interface BPMRootModuleAsyncOptions extends Pick<ModuleMetadata, 'imports
|
|
|
131
157
|
* `@rytass/bpm-core-nestjs-module` to a specific external identity system.
|
|
132
158
|
*/
|
|
133
159
|
readonly memberResolverProvider: Provider<BPMMemberResolver>;
|
|
160
|
+
/**
|
|
161
|
+
* Host-supplied factory that stamps the host's own route metadata onto every
|
|
162
|
+
* BPM GraphQL handler. See
|
|
163
|
+
* `BPMRootModuleOptions.resolverMetadataFactory`.
|
|
164
|
+
*
|
|
165
|
+
* Read at module wiring time rather than from `useFactory`, because Nest
|
|
166
|
+
* builds the resolver metadata before any async factory has run.
|
|
167
|
+
*/
|
|
168
|
+
readonly resolverMetadataFactory?: BPMResolverMetadataFactory;
|
|
134
169
|
/**
|
|
135
170
|
* Host-provided dispatcher for executable workflow service tasks.
|
|
136
171
|
*
|
|
@@ -6,6 +6,7 @@ const tslib_1 = require("tslib");
|
|
|
6
6
|
const common_1 = require("@nestjs/common");
|
|
7
7
|
const attachment_module_1 = require("../attachment/attachment.module");
|
|
8
8
|
const bpm_auth_module_1 = require("../bpm-auth/bpm-auth.module");
|
|
9
|
+
const bpm_resolver_metadata_1 = require("../bpm-auth/bpm-resolver-metadata");
|
|
9
10
|
const calendar_module_1 = require("../calendar/calendar.module");
|
|
10
11
|
const delegation_module_1 = require("../delegation/delegation.module");
|
|
11
12
|
const form_module_1 = require("../form/form.module");
|
|
@@ -53,6 +54,9 @@ let BPMRootModule = BPMRootModule_1 = class BPMRootModule {
|
|
|
53
54
|
* wiring time (no async secret loading needed).
|
|
54
55
|
*/
|
|
55
56
|
static forRoot(options) {
|
|
57
|
+
if (options.resolverMetadataFactory) {
|
|
58
|
+
(0, bpm_resolver_metadata_1.applyBPMResolverMetadata)(options.resolverMetadataFactory);
|
|
59
|
+
}
|
|
56
60
|
const featureModules = createBPMFeatureModules(options);
|
|
57
61
|
return {
|
|
58
62
|
exports: [...featureModules],
|
|
@@ -73,6 +77,9 @@ let BPMRootModule = BPMRootModule_1 = class BPMRootModule {
|
|
|
73
77
|
* during application bootstrap.
|
|
74
78
|
*/
|
|
75
79
|
static forRootAsync(options) {
|
|
80
|
+
if (options.resolverMetadataFactory) {
|
|
81
|
+
(0, bpm_resolver_metadata_1.applyBPMResolverMetadata)(options.resolverMetadataFactory);
|
|
82
|
+
}
|
|
76
83
|
const authOptions = {
|
|
77
84
|
imports: options.imports,
|
|
78
85
|
inject: options.inject,
|
|
@@ -109,6 +116,7 @@ let BPMRootModule = BPMRootModule_1 = class BPMRootModule {
|
|
|
109
116
|
}),
|
|
110
117
|
bpm_auth_module_1.BPMAuthModule.forRootAsync(authOptions),
|
|
111
118
|
identity_module_1.IdentityModule.forRootAsync({
|
|
119
|
+
identityRegisterResolvers: options.identityRegisterResolvers,
|
|
112
120
|
imports: options.imports,
|
|
113
121
|
inject: options.inject,
|
|
114
122
|
memberResolverProvider: options.memberResolverProvider,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bpm-root.module.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm/bpm-root.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAMwB;AAGxB,uEAAmE;AAEnE,iEAA4D;
|
|
1
|
+
{"version":3,"file":"bpm-root.module.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm/bpm-root.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ const tslib_1 = require("tslib");
|
|
|
7
7
|
const common_1 = require("@nestjs/common");
|
|
8
8
|
const bpm_auth_context_extractor_1 = require("./bpm-auth-context.extractor");
|
|
9
9
|
const bpm_auth_guard_1 = require("./bpm-auth.guard");
|
|
10
|
+
const bpm_resolver_access_decorator_1 = require("./bpm-resolver-access.decorator");
|
|
10
11
|
const ADMIN_PERMISSIONS = new Set([
|
|
11
12
|
'bpm:*',
|
|
12
13
|
'bpm:admin',
|
|
@@ -51,9 +52,9 @@ exports.BPMDesignerGuard = BPMDesignerGuard;
|
|
|
51
52
|
exports.BPMDesignerGuard = BPMDesignerGuard = tslib_1.__decorate([
|
|
52
53
|
(0, common_1.Injectable)()
|
|
53
54
|
], BPMDesignerGuard);
|
|
54
|
-
const BPMAdminOnly = () => (0, common_1.UseGuards)(bpm_auth_guard_1.BPMAuthenticatedGuard, BPMAdminGuard);
|
|
55
|
+
const BPMAdminOnly = () => (0, bpm_resolver_access_decorator_1.withBPMResolverAccess)('admin', (0, common_1.UseGuards)(bpm_auth_guard_1.BPMAuthenticatedGuard, BPMAdminGuard));
|
|
55
56
|
exports.BPMAdminOnly = BPMAdminOnly;
|
|
56
|
-
const BPMDesignerOnly = () => (0, common_1.UseGuards)(bpm_auth_guard_1.BPMAuthenticatedGuard, BPMDesignerGuard);
|
|
57
|
+
const BPMDesignerOnly = () => (0, bpm_resolver_access_decorator_1.withBPMResolverAccess)('designer', (0, common_1.UseGuards)(bpm_auth_guard_1.BPMAuthenticatedGuard, BPMDesignerGuard));
|
|
57
58
|
exports.BPMDesignerOnly = BPMDesignerOnly;
|
|
58
59
|
function isBPMAdmin(authContext) {
|
|
59
60
|
return (authContext.roles.includes('BPM_ADMIN') ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bpm-auth.authorization.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm-auth/bpm-auth.authorization.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"bpm-auth.authorization.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm-auth/bpm-auth.authorization.ts"],"names":[],"mappings":";;;AAqEA,gCAOC;AAED,sCAQC;;AAtFD,2CAMwB;AAExB,6EAAqE;AACrE,qDAAyD;AACzD,mFAAwE;AAExE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,OAAO;IACP,WAAW;IACX,WAAW;IACX,aAAa;CACd,CAAC,CAAC;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,OAAO;IACP,WAAW;IACX,WAAW;IACX,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,iBAAiB;IACjB,qBAAqB;IACrB,iBAAiB;IACjB,qBAAqB;CACtB,CAAC,CAAC;AAGI,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,WAAW,CAAC,OAAyB;QACnC,MAAM,WAAW,GAAG,IAAA,kDAAqB,EAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,WAAW,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,2BAAkB,CAAC,kCAAkC,CAAC,CAAC;IACnE,CAAC;CACF,CAAA;AAVY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;GACA,aAAa,CAUzB;AAGM,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,WAAW,CAAC,OAAyB;QACnC,MAAM,WAAW,GAAG,IAAA,kDAAqB,EAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,WAAW,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,2BAAkB,CAAC,qCAAqC,CAAC,CAAC;IACtE,CAAC;CACF,CAAA;AAVY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;GACA,gBAAgB,CAU5B;AAEM,MAAM,YAAY,GAAG,GAAqC,EAAE,CACjE,IAAA,qDAAqB,EACnB,OAAO,EACP,IAAA,kBAAS,EAAC,sCAAqB,EAAE,aAAa,CAAC,CAChD,CAAC;AAJS,QAAA,YAAY,gBAIrB;AAEG,MAAM,eAAe,GAAG,GAAqC,EAAE,CACpE,IAAA,qDAAqB,EACnB,UAAU,EACV,IAAA,kBAAS,EAAC,sCAAqB,EAAE,gBAAgB,CAAC,CACnD,CAAC;AAJS,QAAA,eAAe,mBAIxB;AAEJ,SAAgB,UAAU,CAAC,WAA2B;IACpD,OAAO,CACL,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAC1C,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAClC,CACF,CAAC;AACJ,CAAC;AAED,SAAgB,aAAa,CAAC,WAA2B;IACvD,OAAO,CACL,UAAU,CAAC,WAAW,CAAC;QACvB,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC1C,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAC1C,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CACrC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -4,7 +4,8 @@ exports.BPMCurrentMemberId = exports.BPMCurrentAuthContext = exports.BPMAuthenti
|
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const bpm_auth_guard_1 = require("./bpm-auth.guard");
|
|
6
6
|
const bpm_auth_context_extractor_1 = require("./bpm-auth-context.extractor");
|
|
7
|
-
const
|
|
7
|
+
const bpm_resolver_access_decorator_1 = require("./bpm-resolver-access.decorator");
|
|
8
|
+
const BPMAuthenticated = () => (0, bpm_resolver_access_decorator_1.withBPMResolverAccess)('authenticated', (0, common_1.UseGuards)(bpm_auth_guard_1.BPMAuthenticatedGuard));
|
|
8
9
|
exports.BPMAuthenticated = BPMAuthenticated;
|
|
9
10
|
exports.BPMCurrentAuthContext = (0, common_1.createParamDecorator)((_data, context) => (0, bpm_auth_context_extractor_1.extractBPMAuthContext)(context));
|
|
10
11
|
exports.BPMCurrentMemberId = (0, common_1.createParamDecorator)((_data, context) => (0, bpm_auth_context_extractor_1.extractBPMAuthContext)(context)?.memberId ?? null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bpm-auth.decorators.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm-auth/bpm-auth.decorators.ts"],"names":[],"mappings":";;;AAAA,2CAIwB;AACxB,qDAAyD;AACzD,6EAAqE;
|
|
1
|
+
{"version":3,"file":"bpm-auth.decorators.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm-auth/bpm-auth.decorators.ts"],"names":[],"mappings":";;;AAAA,2CAIwB;AACxB,qDAAyD;AACzD,6EAAqE;AACrE,mFAAwE;AAEjE,MAAM,gBAAgB,GAAG,GAAqC,EAAE,CACrE,IAAA,qDAAqB,EAAC,eAAe,EAAE,IAAA,kBAAS,EAAC,sCAAqB,CAAC,CAAC,CAAC;AAD9D,QAAA,gBAAgB,oBAC8C;AAE9D,QAAA,qBAAqB,GAAG,IAAA,6BAAoB,EACvD,CAAC,KAAc,EAAE,OAAyB,EAAE,EAAE,CAAC,IAAA,kDAAqB,EAAC,OAAO,CAAC,CAC9E,CAAC;AAEW,QAAA,kBAAkB,GAAG,IAAA,6BAAoB,EACpD,CAAC,KAAc,EAAE,OAAyB,EAAE,EAAE,CAC5C,IAAA,kDAAqB,EAAC,OAAO,CAAC,EAAE,QAAQ,IAAI,IAAI,CACnD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BPMResolverAccessLevel } from './bpm-resolver-metadata';
|
|
2
|
+
type BPMResolverDecorator = ClassDecorator & MethodDecorator;
|
|
3
|
+
/**
|
|
4
|
+
* Wraps one of BPM's authorization decorators so the decorated class or method
|
|
5
|
+
* also lands in the resolver registry.
|
|
6
|
+
*
|
|
7
|
+
* The registry is what makes `BPMRootModuleOptions.resolverMetadataFactory`
|
|
8
|
+
* possible: a decorator runs when the class is defined, long before any module
|
|
9
|
+
* option exists, so the only way a host can reach these handlers is for BPM to
|
|
10
|
+
* remember them and replay the host's factory later.
|
|
11
|
+
*/
|
|
12
|
+
export declare function withBPMResolverAccess(access: BPMResolverAccessLevel, decorate: BPMResolverDecorator): BPMResolverDecorator;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withBPMResolverAccess = withBPMResolverAccess;
|
|
4
|
+
const bpm_resolver_metadata_1 = require("./bpm-resolver-metadata");
|
|
5
|
+
/**
|
|
6
|
+
* Wraps one of BPM's authorization decorators so the decorated class or method
|
|
7
|
+
* also lands in the resolver registry.
|
|
8
|
+
*
|
|
9
|
+
* The registry is what makes `BPMRootModuleOptions.resolverMetadataFactory`
|
|
10
|
+
* possible: a decorator runs when the class is defined, long before any module
|
|
11
|
+
* option exists, so the only way a host can reach these handlers is for BPM to
|
|
12
|
+
* remember them and replay the host's factory later.
|
|
13
|
+
*/
|
|
14
|
+
function withBPMResolverAccess(access, decorate) {
|
|
15
|
+
const applyDecorator = decorate;
|
|
16
|
+
const decorator = (target, propertyKey, descriptor) => {
|
|
17
|
+
if (propertyKey === undefined) {
|
|
18
|
+
(0, bpm_resolver_metadata_1.registerBPMResolverClassAccess)(target, access);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
(0, bpm_resolver_metadata_1.registerBPMResolverMethodAccess)(target.constructor, String(propertyKey), access);
|
|
22
|
+
}
|
|
23
|
+
return applyDecorator(target, propertyKey, descriptor);
|
|
24
|
+
};
|
|
25
|
+
return decorator;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=bpm-resolver-access.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bpm-resolver-access.decorator.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/bpm-auth/bpm-resolver-access.decorator.ts"],"names":[],"mappings":";;AAuBA,sDAyBC;AAhDD,mEAIiC;AAUjC;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACnC,MAA8B,EAC9B,QAA8B;IAE9B,MAAM,cAAc,GAAG,QAAuC,CAAC;IAE/D,MAAM,SAAS,GAAqB,CAClC,MAAM,EACN,WAAW,EACX,UAAU,EACJ,EAAE;QACR,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAA,sDAA8B,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,IAAA,uDAA+B,EAC5B,MAA2C,CAAC,WAAW,EACxD,MAAM,CAAC,WAAW,CAAC,EACnB,MAAM,CACP,CAAC;QACJ,CAAC;QAED,OAAO,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC,CAAC;IAEF,OAAO,SAA4C,CAAC;AACtD,CAAC"}
|