@things-factory/auth-base 10.1.111 → 10.1.116
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-server/ai-entry/access-assistant.d.ts +8 -0
- package/dist-server/ai-entry/access-assistant.js +9 -1
- package/dist-server/ai-entry/access-assistant.js.map +1 -1
- package/dist-server/service/appliance/appliance-query.js +4 -2
- package/dist-server/service/appliance/appliance-query.js.map +1 -1
- package/dist-server/service/application/application-query.js +2 -1
- package/dist-server/service/application/application-query.js.map +1 -1
- package/dist-server/service/auth-provider/auth-provider-query.js +2 -1
- package/dist-server/service/auth-provider/auth-provider-query.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -1
- package/dist-server/service/index.js +4 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/invitation/invitation-query.js +2 -1
- package/dist-server/service/invitation/invitation-query.js.map +1 -1
- package/dist-server/service/login-history/login-history-query.js +8 -4
- package/dist-server/service/login-history/login-history-query.js.map +1 -1
- package/dist-server/service/partner/partner-query.js +2 -1
- package/dist-server/service/partner/partner-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/tests/access-entry-targets-db.test.ts +36 -0
- package/tests/list-inheritance-db.test.ts +149 -0
|
@@ -46,5 +46,13 @@ export declare function accessAssistantMode(): {
|
|
|
46
46
|
entryTargets: string[];
|
|
47
47
|
requireToolOnFirstTurn: boolean;
|
|
48
48
|
placeholderKey: string;
|
|
49
|
+
introKeys: {
|
|
50
|
+
title: string;
|
|
51
|
+
subtitle: string;
|
|
52
|
+
};
|
|
53
|
+
exampleKeys: {
|
|
54
|
+
labelKey: string;
|
|
55
|
+
itemKeys: string[];
|
|
56
|
+
}[];
|
|
49
57
|
};
|
|
50
58
|
export {};
|
|
@@ -139,7 +139,15 @@ function accessAssistantMode() {
|
|
|
139
139
|
toolCategories: [exports.AUTH_ACCESS_TOOLS],
|
|
140
140
|
entryTargets: [access_entry_targets_js_1.AUTH_ACCESS_DECISION],
|
|
141
141
|
requireToolOnFirstTurn: true,
|
|
142
|
-
placeholderKey: 'access-request.dock.placeholder'
|
|
142
|
+
placeholderKey: 'access-request.dock.placeholder',
|
|
143
|
+
/* The empty conversation says what this one is for - without it the dock fell back to board authoring. */
|
|
144
|
+
introKeys: { title: 'access-request.dock.intro title', subtitle: 'access-request.dock.intro subtitle' },
|
|
145
|
+
exampleKeys: [
|
|
146
|
+
{
|
|
147
|
+
labelKey: 'access-request.dock.examples',
|
|
148
|
+
itemKeys: ['access-request.dock.example today', 'access-request.dock.example smallest', 'access-request.dock.example one person']
|
|
149
|
+
}
|
|
150
|
+
]
|
|
143
151
|
};
|
|
144
152
|
}
|
|
145
153
|
//# sourceMappingURL=access-assistant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-assistant.js","sourceRoot":"","sources":["../../server/ai-entry/access-assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * What the assistant reads to draft access decisions, and the mode an application registers (ADR-0103 decision 6).\n *\n * ── Why a read tool and not the screen's context ─────────────────────────\n * The screen's `hostContext` goes to the tools (`toolContext.host`), never into the model's prompt\n * (ai-client-base registry-assistant.ts: the prompt is `systemPrompt + guidance`). Pending requests put there\n * would be invisible to the model. So the model reads them through this tool, run on the server as the caller:\n * this domain only, only for someone who may decide, and never the caller's own requests.\n *\n * ── Plain data ────────────────────────────────────────────────────────────\n * Like the entry targets: no dependency on the assistant. An application that runs it registers the category,\n * the mode and the two targets. One that does not register them has no tool - whether colleagues' names and\n * reasons go to an external model is that product's decision.\n */\nimport { AUTH_ACCESS_DECISION } from './access-entry-targets.js'\n\nexport const AUTH_ACCESS_TOOLS = 'auth-access'\nexport const AUTH_ACCESS_MODE = 'auth.access'\n/** The subject the access request list stands for - the application sets its surface to this on that screen. */\nexport const ACCESS_REQUESTS_SUBJECT = 'access-requests'\n/** The screen an application recognises (auth-ui's page tag and route). */\nexport const ACCESS_REQUESTS_PAGE = { tagname: 'access-requests-page', route: 'access-requests' }\n\n/** The declaration the decision door carries - who may read pending requests to decide them. */\nconst DECIDER = { category: 'user', privilege: 'mutation', owner: true }\n\ntype ReadSpec = {\n kind: 'read'\n name: string\n description: string\n doors: string[]\n schema: any\n builder: (args: any, context: { state?: any }) => any | Promise<any>\n}\n\nexport type AccessToolCategory = { name: string; description?: string; guidance: string; specs: ReadSpec[] }\n\n/**\n * The pending requests the caller may decide, each with the roles that would grant it, smallest first.\n * Refuses a caller who may not decide - the gate in front of it says the same, and this says it again on the server.\n */\nexport async function pendingRequestsToDecide(state: any) {\n const [{ judgePermission }, access, { getRepository }, { AccessRequest, AccessRequestStatus }, { effectiveState }] = await Promise.all([\n import('../utils/check-permission.js'),\n import('../controllers/access-request.js'),\n import('@things-factory/shell'),\n import('../service/access-request/access-request.js'),\n import('../utils/access-request-review.js')\n ])\n const { domain, user } = state || {}\n if (!domain?.id || !user?.id) return { refused: 'no-domain' }\n\n const judgement = await judgePermission(DECIDER, user, domain, state.unsafeIP, state.prohibitedPrivileges)\n if (judgement.permitted !== true) return { refused: 'not-a-decider' }\n\n const now = new Date()\n const rows = await getRepository(AccessRequest).find({\n where: { domain: { id: domain.id }, state: AccessRequestStatus.PENDING },\n relations: ['requester'],\n order: { createdAt: 'ASC' },\n take: 200\n })\n\n const requests = []\n for (const row of rows) {\n if (row.requester?.id === user.id) continue\n if (effectiveState(row.state as any, row.expiresAt, now) !== 'PENDING') continue\n const candidates = await access.rolesGranting(row.category, row.privilege, domain)\n requests.push({\n request: `${row.requester?.name || row.requester?.email || ''} · ${row.category}:${row.privilege}`,\n requester: row.requester?.name || row.requester?.email || '',\n privilege: `${row.category}:${row.privilege}`,\n refusedAt: row.operationName || null,\n reason: row.reason || null,\n timesAsked: row.count,\n askedAt: row.createdAt,\n roles: candidates.map(({ name, privilegeCount }) => ({ name, privilegeCount }))\n })\n }\n return { requests }\n}\n\nexport function accessToolCategory(): AccessToolCategory {\n return {\n name: AUTH_ACCESS_TOOLS,\n description: 'access requests waiting for a decision in this domain',\n guidance: [\n 'To draft decisions on access requests, call listPendingAccessRequests first and draft only from what it returns.',\n 'Propose GRANT with the role that has the fewest privileges among the roles listed for that request; name another role only when the person asks.',\n 'Never write a reason to deny - ask the person for it. Never say a request was granted or denied: the person presses the card.',\n 'If a request lists no roles, say no role in this domain grants it and that a role must hold it first; do not propose it.'\n ].join('\\n'),\n specs: [\n {\n kind: 'read',\n name: 'listPendingAccessRequests',\n description:\n 'Lists the access requests in this domain that are waiting for a decision the caller may make, each with the roles that would grant it (fewest privileges first).',\n /* Reading requests and their candidate roles - both doors; the second carries the deciding declaration. */\n doors: ['Query.accessRequests', 'Query.rolesGranting'],\n schema: { type: 'object', properties: {} },\n builder: (_args, context) => pendingRequestsToDecide(context?.state)\n }\n ]\n }\n}\n\n/** The mode an application registers for the access request list. Words are auth-ui's. */\nexport function accessAssistantMode() {\n return {\n kind: AUTH_ACCESS_MODE,\n subjects: [ACCESS_REQUESTS_SUBJECT],\n defaultFor: [ACCESS_REQUESTS_SUBJECT],\n labelKey: 'access-request.dock.mode',\n systemPrompt:\n 'You help the person deciding access requests in this domain. You draft decisions as a card the person reviews and presses; the server checks each decision and the card shows what it found.',\n toolCategories: [AUTH_ACCESS_TOOLS],\n entryTargets: [AUTH_ACCESS_DECISION],\n requireToolOnFirstTurn: true,\n placeholderKey: 'access-request.dock.placeholder'\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"access-assistant.js","sourceRoot":"","sources":["../../server/ai-entry/access-assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * What the assistant reads to draft access decisions, and the mode an application registers (ADR-0103 decision 6).\n *\n * ── Why a read tool and not the screen's context ─────────────────────────\n * The screen's `hostContext` goes to the tools (`toolContext.host`), never into the model's prompt\n * (ai-client-base registry-assistant.ts: the prompt is `systemPrompt + guidance`). Pending requests put there\n * would be invisible to the model. So the model reads them through this tool, run on the server as the caller:\n * this domain only, only for someone who may decide, and never the caller's own requests.\n *\n * ── Plain data ────────────────────────────────────────────────────────────\n * Like the entry targets: no dependency on the assistant. An application that runs it registers the category,\n * the mode and the two targets. One that does not register them has no tool - whether colleagues' names and\n * reasons go to an external model is that product's decision.\n */\nimport { AUTH_ACCESS_DECISION } from './access-entry-targets.js'\n\nexport const AUTH_ACCESS_TOOLS = 'auth-access'\nexport const AUTH_ACCESS_MODE = 'auth.access'\n/** The subject the access request list stands for - the application sets its surface to this on that screen. */\nexport const ACCESS_REQUESTS_SUBJECT = 'access-requests'\n/** The screen an application recognises (auth-ui's page tag and route). */\nexport const ACCESS_REQUESTS_PAGE = { tagname: 'access-requests-page', route: 'access-requests' }\n\n/** The declaration the decision door carries - who may read pending requests to decide them. */\nconst DECIDER = { category: 'user', privilege: 'mutation', owner: true }\n\ntype ReadSpec = {\n kind: 'read'\n name: string\n description: string\n doors: string[]\n schema: any\n builder: (args: any, context: { state?: any }) => any | Promise<any>\n}\n\nexport type AccessToolCategory = { name: string; description?: string; guidance: string; specs: ReadSpec[] }\n\n/**\n * The pending requests the caller may decide, each with the roles that would grant it, smallest first.\n * Refuses a caller who may not decide - the gate in front of it says the same, and this says it again on the server.\n */\nexport async function pendingRequestsToDecide(state: any) {\n const [{ judgePermission }, access, { getRepository }, { AccessRequest, AccessRequestStatus }, { effectiveState }] = await Promise.all([\n import('../utils/check-permission.js'),\n import('../controllers/access-request.js'),\n import('@things-factory/shell'),\n import('../service/access-request/access-request.js'),\n import('../utils/access-request-review.js')\n ])\n const { domain, user } = state || {}\n if (!domain?.id || !user?.id) return { refused: 'no-domain' }\n\n const judgement = await judgePermission(DECIDER, user, domain, state.unsafeIP, state.prohibitedPrivileges)\n if (judgement.permitted !== true) return { refused: 'not-a-decider' }\n\n const now = new Date()\n const rows = await getRepository(AccessRequest).find({\n where: { domain: { id: domain.id }, state: AccessRequestStatus.PENDING },\n relations: ['requester'],\n order: { createdAt: 'ASC' },\n take: 200\n })\n\n const requests = []\n for (const row of rows) {\n if (row.requester?.id === user.id) continue\n if (effectiveState(row.state as any, row.expiresAt, now) !== 'PENDING') continue\n const candidates = await access.rolesGranting(row.category, row.privilege, domain)\n requests.push({\n request: `${row.requester?.name || row.requester?.email || ''} · ${row.category}:${row.privilege}`,\n requester: row.requester?.name || row.requester?.email || '',\n privilege: `${row.category}:${row.privilege}`,\n refusedAt: row.operationName || null,\n reason: row.reason || null,\n timesAsked: row.count,\n askedAt: row.createdAt,\n roles: candidates.map(({ name, privilegeCount }) => ({ name, privilegeCount }))\n })\n }\n return { requests }\n}\n\nexport function accessToolCategory(): AccessToolCategory {\n return {\n name: AUTH_ACCESS_TOOLS,\n description: 'access requests waiting for a decision in this domain',\n guidance: [\n 'To draft decisions on access requests, call listPendingAccessRequests first and draft only from what it returns.',\n 'Propose GRANT with the role that has the fewest privileges among the roles listed for that request; name another role only when the person asks.',\n 'Never write a reason to deny - ask the person for it. Never say a request was granted or denied: the person presses the card.',\n 'If a request lists no roles, say no role in this domain grants it and that a role must hold it first; do not propose it.'\n ].join('\\n'),\n specs: [\n {\n kind: 'read',\n name: 'listPendingAccessRequests',\n description:\n 'Lists the access requests in this domain that are waiting for a decision the caller may make, each with the roles that would grant it (fewest privileges first).',\n /* Reading requests and their candidate roles - both doors; the second carries the deciding declaration. */\n doors: ['Query.accessRequests', 'Query.rolesGranting'],\n schema: { type: 'object', properties: {} },\n builder: (_args, context) => pendingRequestsToDecide(context?.state)\n }\n ]\n }\n}\n\n/** The mode an application registers for the access request list. Words are auth-ui's. */\nexport function accessAssistantMode() {\n return {\n kind: AUTH_ACCESS_MODE,\n subjects: [ACCESS_REQUESTS_SUBJECT],\n defaultFor: [ACCESS_REQUESTS_SUBJECT],\n labelKey: 'access-request.dock.mode',\n systemPrompt:\n 'You help the person deciding access requests in this domain. You draft decisions as a card the person reviews and presses; the server checks each decision and the card shows what it found.',\n toolCategories: [AUTH_ACCESS_TOOLS],\n entryTargets: [AUTH_ACCESS_DECISION],\n requireToolOnFirstTurn: true,\n placeholderKey: 'access-request.dock.placeholder',\n /* The empty conversation says what this one is for - without it the dock fell back to board authoring. */\n introKeys: { title: 'access-request.dock.intro title', subtitle: 'access-request.dock.intro subtitle' },\n exampleKeys: [\n {\n labelKey: 'access-request.dock.examples',\n itemKeys: ['access-request.dock.example today', 'access-request.dock.example smallest', 'access-request.dock.example one person']\n }\n ]\n }\n}\n"]}
|
|
@@ -17,7 +17,8 @@ let ApplianceQuery = class ApplianceQuery {
|
|
|
17
17
|
const { domain } = context.state;
|
|
18
18
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
19
19
|
domain,
|
|
20
|
-
|
|
20
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
21
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
21
22
|
repository: (0, shell_1.getRepository)(appliance_js_1.Appliance),
|
|
22
23
|
alias: 'appliance',
|
|
23
24
|
searchables: ['name', 'description']
|
|
@@ -29,7 +30,8 @@ let ApplianceQuery = class ApplianceQuery {
|
|
|
29
30
|
const { domain } = context.state;
|
|
30
31
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
31
32
|
domain,
|
|
32
|
-
|
|
33
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
34
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
33
35
|
repository: (0, shell_1.getRepository)(appliance_js_1.Appliance),
|
|
34
36
|
alias: 'appliance',
|
|
35
37
|
searchables: ['name', 'description']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appliance-query.js","sourceRoot":"","sources":["../../../server/service/appliance/appliance-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,
|
|
1
|
+
{"version":3,"file":"appliance-query.js","sourceRoot":"","sources":["../../../server/service/appliance/appliance-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { getQueryBuilderFromListParams, InheritedValueType, Domain, getRepository, ListParam } from '@things-factory/shell'\n\nimport { offersCredentialRevocation } from '../../utils/credential-features.js'\nimport { Appliance } from '../appliance/appliance.js'\nimport { User, UserStatus } from '../user/user.js'\nimport { ApplianceList } from './appliance-types.js'\n\n@Resolver(Appliance)\nexport class ApplianceQuery {\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => Appliance, { description: ' To fetch appliance' })\n async appliance(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Appliance> {\n const { domain } = context.state\n return await getRepository(Appliance).findOneBy({ domain: { id: domain.id }, id })\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => ApplianceList, { description: 'To fetch multiple appliance' })\n async appliances(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ApplianceList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(Appliance),\n alias: 'appliance',\n searchables: ['name', 'description']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => ApplianceList, { description: 'To fetch multiple appliance' })\n async edges(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<ApplianceList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(Appliance),\n alias: 'appliance',\n searchables: ['name', 'description']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /*\n * Does revoking an appliance credential work here? (ADR-0085 decision 1.)\n *\n * ── Why the screen has to ask ───────────────────────────────────────────\n * Revocation is behind `credential/revocable`, and an installation that never configured it\n * has no such door — `revokeApplianceCredential` answers 404. The screen cannot read the\n * config, so without this it would either hide a feature the installation paid for or show a\n * button that always refuses. The second is the worse one: it reads as a broken product\n * rather than as something nobody turned on.\n *\n * ── Why it carries the mutation's own gate ──────────────────────────────\n * The same `category` / `privilege` pair as `revokeApplianceCredential`, so what comes back is\n * not \"the installation has this\" but **\"pressing it would work for you\"**. Those differ for a\n * reader who may list appliances and may not act on their credentials, and a button should\n * follow the second. A refusal here reaches the client as an error, which it reads the same\n * way as false.\n */\n @Directive('@privilege(category: \"security\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Query(returns => Boolean, { description: 'Whether this installation offers appliance credential revocation' })\n async applianceCredentialRevocable(): Promise<boolean> {\n return offersCredentialRevocation()\n }\n\n @FieldResolver(type => String)\n async accessToken(@Root() appliance: Appliance, @Ctx() context: ResolverContext) {\n return appliance.accessToken\n }\n\n /*\n * Revocation is recorded on the shadow user, so the answer is not on the row that was asked\n * for. INACTIVE means revoked and nothing else does: `ensureApplianceUser` creates the user\n * ACTIVATED, `generateApplianceSecret` puts it back to ACTIVATED, and `revokeApplianceCredential`\n * is the one place that sets INACTIVE.\n *\n * An appliance with no shadow user at all is not revoked — it is one nothing was ever issued\n * for, which is the state a freshly registered appliance is in.\n */\n @FieldResolver(type => Boolean)\n async credentialRevoked(@Root() appliance: Appliance): Promise<boolean> {\n const appuser = await getRepository(User).findOneBy({ reference: appliance.id, userType: 'appliance' })\n\n return appuser?.status === UserStatus.INACTIVE\n }\n\n @FieldResolver(type => Domain)\n async domain(@Ctx() context: ResolverContext) {\n return context.state.domain\n }\n\n @FieldResolver(type => User)\n async updater(@Root() appliance: Appliance): Promise<User> {\n return await getRepository(User).findOneBy({ id: appliance.updaterId })\n }\n\n @FieldResolver(type => User)\n async creator(@Root() appliance: Appliance): Promise<User> {\n return await getRepository(User).findOneBy({ id: appliance.creatorId })\n }\n}\n"]}
|
|
@@ -18,7 +18,8 @@ let ApplicationQuery = class ApplicationQuery {
|
|
|
18
18
|
const { domain } = context.state;
|
|
19
19
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
20
20
|
domain,
|
|
21
|
-
|
|
21
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
22
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
22
23
|
repository: (0, shell_1.getRepository)(application_js_1.Application),
|
|
23
24
|
alias: 'application',
|
|
24
25
|
searchables: ['name', 'description']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-query.js","sourceRoot":"","sources":["../../../server/service/application/application-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,
|
|
1
|
+
{"version":3,"file":"application-query.js","sourceRoot":"","sources":["../../../server/service/application/application-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Directive, Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { getQueryBuilderFromListParams, InheritedValueType, Domain, getRepository, ListParam } from '@things-factory/shell'\n\nimport { buildAuthURL } from '../../utils/build-auth-url.js'\n\nimport { Role } from '../role/role.js'\nimport { User } from '../user/user.js'\nimport { Application } from './application.js'\nimport { ApplicationList } from './application-types.js'\n\n@Resolver(Application)\nexport class ApplicationQuery {\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => Application, { description: 'To fetch application' })\n async application(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Application> {\n const repository = getRepository(Application)\n\n return await repository.findOneBy({ id })\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => ApplicationList, { description: 'To fetch multiple application' })\n async applications(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext) {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(Application),\n alias: 'application',\n searchables: ['name', 'description']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => String)\n async availableScopes(@Ctx() context: ResolverContext): Promise<string> {\n const { domain } = context.state\n const roles = await getRepository(Role).findBy({ domain: { id: domain.id } })\n\n return roles.map((role: Role) => role.name).join(' ')\n }\n\n @FieldResolver(type => String)\n async accessTokenUrl(@Ctx() context: ResolverContext): Promise<string> {\n return buildAuthURL('/oauth/access-token', context)\n }\n\n @FieldResolver(type => String)\n async authUrl(@Ctx() context: ResolverContext): Promise<string> {\n return buildAuthURL('/oauth/authorize', context)\n }\n\n @FieldResolver(type => Domain)\n async domain(@Ctx() context: ResolverContext) {\n return context.state.domain\n }\n\n @FieldResolver(type => User)\n async updater(@Root() application: Application): Promise<User> {\n return await getRepository(User).findOneBy({ id: application.updaterId })\n }\n\n @FieldResolver(type => User)\n async creator(@Root() application: Application): Promise<User> {\n return await getRepository(User).findOneBy({ id: application.creatorId })\n }\n}\n"]}
|
|
@@ -22,7 +22,8 @@ let AuthProviderQuery = class AuthProviderQuery {
|
|
|
22
22
|
const { domain } = context.state;
|
|
23
23
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
24
24
|
domain,
|
|
25
|
-
|
|
25
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
26
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
26
27
|
repository: await (0, shell_1.getRepository)(auth_provider_js_1.AuthProvider),
|
|
27
28
|
searchables: ['type']
|
|
28
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider-query.js","sourceRoot":"","sources":["../../../server/service/auth-provider/auth-provider-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"auth-provider-query.js","sourceRoot":"","sources":["../../../server/service/auth-provider/auth-provider-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, InheritedValueType, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '../user/user.js'\nimport { AuthProvider, AuthProviderTypeList } from './auth-provider.js'\nimport { AuthProviderList } from './auth-provider-type.js'\n\n@Resolver(AuthProvider)\nexport class AuthProviderQuery {\n @Query(returns => AuthProviderTypeList!, { nullable: true, description: 'To fetch a AuthProvider' })\n authProviderTypes(@Ctx() context: ResolverContext): AuthProviderTypeList {\n const { domain } = context.state\n\n return AuthProvider.getAuthProviderTypes()\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => AuthProvider!, { nullable: true, description: 'To fetch a AuthProvider' })\n async authProvider(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<AuthProvider> {\n const { domain } = context.state\n\n return await getRepository(AuthProvider).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => AuthProviderList, { description: 'To fetch multiple AuthProviders' })\n async authProviders(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<AuthProviderList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: await getRepository(AuthProvider),\n searchables: ['type']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => String)\n clientSecret(@Root() authProvider: AuthProvider): string {\n const clientSecret = authProvider.clientSecret\n\n if (!clientSecret || clientSecret.length <= 2) {\n return clientSecret // 입력 문자열의 길이가 2 이하인 경우 그대로 반환\n }\n const firstChar = clientSecret.charAt(0)\n const lastChar = clientSecret.charAt(clientSecret.length - 1)\n const maskedPart = '*'.repeat(clientSecret.length - 2)\n\n return firstChar + maskedPart + lastChar\n }\n\n @FieldResolver(type => String)\n privateKey(@Root() authProvider: AuthProvider): string {\n const privateKey = authProvider.privateKey\n\n if (!privateKey || privateKey.length <= 2) {\n return privateKey // 입력 문자열의 길이가 2 이하인 경우 그대로 반환\n }\n const firstChar = privateKey.charAt(0)\n const lastChar = privateKey.charAt(privateKey.length - 1)\n const maskedPart = '*'.repeat(privateKey.length - 2)\n\n return firstChar + maskedPart + lastChar\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() authProvider: AuthProvider): Promise<Domain> {\n return authProvider.domainId && (await getRepository(Domain).findOneBy({ id: authProvider.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() authProvider: AuthProvider): Promise<User> {\n return authProvider.updaterId && (await getRepository(User).findOneBy({ id: authProvider.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() authProvider: AuthProvider): Promise<User> {\n return authProvider.creatorId && (await getRepository(User).findOneBy({ id: authProvider.creatorId }))\n }\n}\n"]}
|
|
@@ -6,6 +6,7 @@ export * from './privilege/privilege.js';
|
|
|
6
6
|
export * from './role/role.js';
|
|
7
7
|
export * from './privilege/privilege-axis.js';
|
|
8
8
|
export { privilegeOfField, type FieldGate } from './privilege/privilege-directive.js';
|
|
9
|
+
export { privilegeRejection } from './privilege/privilege-rejection.js';
|
|
9
10
|
export { type OpenFieldsDeclaration } from './privilege/open-field-rule.js';
|
|
10
11
|
export * from './role-template/role-template.js';
|
|
11
12
|
export * from './role-template/role-template-types.js';
|
|
@@ -32,7 +33,7 @@ export * from './role/role-types.js';
|
|
|
32
33
|
export * from './user/user-types.js';
|
|
33
34
|
export * from './domain-link/domain-link-types.js';
|
|
34
35
|
export * from './access-request/access-request-types.js';
|
|
35
|
-
export declare const entities: (typeof import("./
|
|
36
|
+
export declare const entities: (typeof import("./users-auth-providers/users-auth-providers.js").UsersAuthProviders | typeof import("./auth-provider/auth-provider.js").AuthProvider | typeof import("./application/application.js").Application | typeof import("./appliance/appliance.js").Appliance | typeof import("./privilege/privilege.js").Privilege | typeof import("./role/role.js").Role | typeof import("./user/user.js").User | typeof import("./partner/partner.js").Partner | typeof import("./granted-role/granted-role.js").GrantedRole | typeof import("./invitation/invitation.js").Invitation | typeof import("./password-history/password-history.js").PasswordHistory | typeof import("./verification-token/verification-token.js").VerificationToken | typeof import("./verification-token/verification-token.js").VerificationTokenType | typeof import("./login-history/login-history.js").LoginHistory | typeof import("./web-auth-credential/web-auth-credential.js").WebAuthCredential | typeof import("./domain-link/domain-link.js").DomainLink | typeof import("./domain-owner/domain-owner.js").DomainOwner | typeof import("./access-request/access-request.js").AccessRequest)[];
|
|
36
37
|
export declare const schema: {
|
|
37
38
|
typeDefs: {
|
|
38
39
|
privilegeDirectiveTypeDefs: import("graphql").DocumentNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.schema = exports.entities = exports.privilegeOfField = void 0;
|
|
3
|
+
exports.schema = exports.entities = exports.privilegeRejection = exports.privilegeOfField = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
/* IMPORT ENTITIES AND RESOLVERS */
|
|
6
6
|
const index_js_1 = require("./access-request/index.js");
|
|
@@ -36,6 +36,9 @@ tslib_1.__exportStar(require("./privilege/privilege-axis.js"), exports);
|
|
|
36
36
|
/* What a field asks for, by name — for another entrance to the same door (operato-twin ADR-0072 decision 5). */
|
|
37
37
|
var privilege_directive_js_2 = require("./privilege/privilege-directive.js");
|
|
38
38
|
Object.defineProperty(exports, "privilegeOfField", { enumerable: true, get: function () { return privilege_directive_js_2.privilegeOfField; } });
|
|
39
|
+
/* Other entrances report AUTH's refusal without copying its cause or localized wording. */
|
|
40
|
+
var privilege_rejection_js_1 = require("./privilege/privilege-rejection.js");
|
|
41
|
+
Object.defineProperty(exports, "privilegeRejection", { enumerable: true, get: function () { return privilege_rejection_js_1.privilegeRejection; } });
|
|
39
42
|
tslib_1.__exportStar(require("./role-template/role-template.js"), exports);
|
|
40
43
|
tslib_1.__exportStar(require("./role-template/role-template-types.js"), exports);
|
|
41
44
|
tslib_1.__exportStar(require("./user/user.js"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,mCAAmC;AACnC,wDAAkH;AAClH,8DAGwC;AACxC,uDAA+G;AAC/G,qDAAwE;AACxE,mDAAqG;AACrG,qDAA2G;AAC3G,0DAAkF;AAClF,sDAA2G;AAC3G,oDAAuG;AACvG,wDAA8G;AAC9G,kDAA+F;AAC/F,2DAAiF;AACjF,oDAAqG;AACrG,+EAA2G;AAC3G,qDAA6C;AAC7C,+CAAsF;AACtF,wDAA6E;AAC7E,+CAAsF;AACtF,6DAAqF;AACrF,8DAAsF;AACtF,sDAAwG;AACxG,uDAA4G;AAE5G,yBAAyB;AACzB,yFAA8D;AAC9D,2EAAgD;AAChD,uEAA4C;AAC5C,mEAAwC;AACxC,mEAAwC;AACxC,yDAA8B;AAC9B,wEAA6C;AAC7C,gHAAgH;AAChH,6EAAqF;AAA5E,0HAAA,gBAAgB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,mCAAmC;AACnC,wDAAkH;AAClH,8DAGwC;AACxC,uDAA+G;AAC/G,qDAAwE;AACxE,mDAAqG;AACrG,qDAA2G;AAC3G,0DAAkF;AAClF,sDAA2G;AAC3G,oDAAuG;AACvG,wDAA8G;AAC9G,kDAA+F;AAC/F,2DAAiF;AACjF,oDAAqG;AACrG,+EAA2G;AAC3G,qDAA6C;AAC7C,+CAAsF;AACtF,wDAA6E;AAC7E,+CAAsF;AACtF,6DAAqF;AACrF,8DAAsF;AACtF,sDAAwG;AACxG,uDAA4G;AAE5G,yBAAyB;AACzB,yFAA8D;AAC9D,2EAAgD;AAChD,uEAA4C;AAC5C,mEAAwC;AACxC,mEAAwC;AACxC,yDAA8B;AAC9B,wEAA6C;AAC7C,gHAAgH;AAChH,6EAAqF;AAA5E,0HAAA,gBAAgB,OAAA;AACzB,2FAA2F;AAC3F,6EAAuE;AAA9D,4HAAA,kBAAkB,OAAA;AAG3B,2EAAgD;AAChD,iFAAsD;AACtD,yDAA8B;AAC9B,+DAAoC;AACpC,yEAA8C;AAC9C,qEAA0C;AAC1C,uEAA4C;AAC5C,iFAAsD;AACtD,qFAA0D;AAC1D,2EAAgD;AAChD,uFAA4D;AAC5D,uEAA4C;AAC5C,yEAA8C;AAC9C,6EAAkD;AAElD,kBAAkB;AAClB,6EAAkD;AAClD,yEAA8C;AAC9C,6EAAkD;AAClD,uFAA4D;AAC5D,2EAAgD;AAChD,qEAA0C;AAC1C,yEAA8C;AAC9C,+DAAoC;AACpC,+DAAoC;AACpC,6EAAkD;AAClD,mFAAwD;AAE3C,QAAA,QAAQ,GAAG;IACtB,cAAc;IACd,GAAG,mBAA0B;IAC7B,GAAG,mBAAoB;IACvB,GAAG,mBAAmB;IACtB,GAAG,mBAAiB;IACpB,GAAG,oBAAiB;IACpB,GAAG,oBAAY;IACf,GAAG,oBAAY;IACf,GAAG,oBAAe;IAClB,GAAG,mBAAmB;IACtB,GAAG,mBAAkB;IACrB,GAAG,oBAAuB;IAC1B,GAAG,oBAAyB;IAC5B,GAAG,oBAAoB;IACvB,GAAG,oBAAyB;IAC5B,GAAG,oBAAkB;IACrB,GAAG,oBAAmB;IACtB,GAAG,mBAAqB;CACzB,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,QAAQ,EAAE;QACR,0BAA0B,EAA1B,mDAA0B;KAC3B;IAED,6FAA6F;IAC7F,UAAU,EAAV,2BAAU;IAEV,eAAe,EAAE;QACf,sBAAsB;QACtB,GAAG,oBAA2B;QAC9B,GAAG,oBAAqB;QACxB,GAAG,oBAAoB;QACvB,GAAG,oBAAkB;QACrB,GAAG,qBAAkB;QACrB,GAAG,qBAAa;QAChB,GAAG,qBAAqB;QACxB,GAAG,qBAAa;QAChB,GAAG,qBAAgB;QACnB,GAAG,oBAAmB;QACtB,GAAG,oBAAkB;QACrB,GAAG,oBAAkB;QACrB,GAAG,oBAAuB;QAC1B,GAAG,qBAAoB;QACvB,GAAG,qBAAkB;QACrB,GAAG,qBAAoB;QACvB,GAAG,oBAAsB;KAC1B;IACD,UAAU,EAAE;QACV,SAAS,EAAE,mDAA0B;KACtC;CACF,CAAA","sourcesContent":["/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as AccessRequestEntities, resolvers as AccessRequestResolvers } from './access-request/index.js'\nimport {\n entities as UsersAuthProvidersEntities,\n resolvers as UsersAuthProvidersResolvers\n} from './users-auth-providers/index.js'\nimport { entities as AuthProviderEntities, resolvers as AuthProviderResolvers } from './auth-provider/index.js'\nimport { resolvers as AppbindingResolver } from './app-binding/index.js'\nimport { entities as ApplianceEntities, resolvers as ApplianceResolvers } from './appliance/index.js'\nimport { entities as ApplicationEntities, resolvers as ApplicationResolvers } from './application/index.js'\nimport { resolvers as DomainGeneratorResolver } from './domain-generator/index.js'\nimport { entities as GrantedRoleEntities, resolvers as GrantedRoleResolver } from './granted-role/index.js'\nimport { entities as InvitationEntities, resolvers as InvitationResolver } from './invitation/index.js'\nimport { entities as LoginHistoryEntities, resolvers as LoginHistoryResolver } from './login-history/index.js'\nimport { entities as PartnerEntities, resolvers as PartnerResolvers } from './partner/index.js'\nimport { entities as PasswordHistoryEntities } from './password-history/index.js'\nimport { entities as PrivilegeEntities, resolvers as PrivilegeResolvers } from './privilege/index.js'\nimport { privilegeDirectiveResolver, privilegeDirectiveTypeDefs } from './privilege/privilege-directive.js'\nimport { openFields } from './open-fields.js'\nimport { entities as RoleEntities, resolvers as RoleResolvers } from './role/index.js'\nimport { resolvers as RoleTemplateResolvers } from './role-template/index.js'\nimport { entities as UserEntities, resolvers as UserResolvers } from './user/index.js'\nimport { entities as VerificationTokenEntities } from './verification-token/index.js'\nimport { entities as WebAuthCredentialEntities } from './web-auth-credential/index.js'\nimport { entities as DomainLinkEntities, resolvers as DomainLinkResolver } from './domain-link/index.js'\nimport { entities as DomainOwnerEntities, resolvers as DomainOwnerResolvers } from './domain-owner/index.js'\n\n/* EXPORT ENTITY TYPES */\nexport * from './users-auth-providers/users-auth-providers.js'\nexport * from './auth-provider/auth-provider.js'\nexport * from './application/application.js'\nexport * from './appliance/appliance.js'\nexport * from './privilege/privilege.js'\nexport * from './role/role.js'\nexport * from './privilege/privilege-axis.js'\n/* What a field asks for, by name — for another entrance to the same door (operato-twin ADR-0072 decision 5). */\nexport { privilegeOfField, type FieldGate } from './privilege/privilege-directive.js'\n/* Other entrances report AUTH's refusal without copying its cause or localized wording. */\nexport { privilegeRejection } from './privilege/privilege-rejection.js'\n/* How a module declares the fields it leaves open — see `privilege/open-field-rule.ts`. */\nexport { type OpenFieldsDeclaration } from './privilege/open-field-rule.js'\nexport * from './role-template/role-template.js'\nexport * from './role-template/role-template-types.js'\nexport * from './user/user.js'\nexport * from './partner/partner.js'\nexport * from './granted-role/granted-role.js'\nexport * from './invitation/invitation.js'\nexport * from './app-binding/app-binding.js'\nexport * from './password-history/password-history.js'\nexport * from './verification-token/verification-token.js'\nexport * from './login-history/login-history.js'\nexport * from './web-auth-credential/web-auth-credential.js'\nexport * from './domain-link/domain-link.js'\nexport * from './domain-owner/domain-owner.js'\nexport * from './access-request/access-request.js'\n\n/* EXPORT TYPES */\nexport * from './app-binding/app-binding-types.js'\nexport * from './appliance/appliance-types.js'\nexport * from './application/application-types.js'\nexport * from './domain-generator/domain-generator-types.js'\nexport * from './invitation/invitation-types.js'\nexport * from './partner/partner-types.js'\nexport * from './privilege/privilege-types.js'\nexport * from './role/role-types.js'\nexport * from './user/user-types.js'\nexport * from './domain-link/domain-link-types.js'\nexport * from './access-request/access-request-types.js'\n\nexport const entities = [\n /* ENTITIES */\n ...UsersAuthProvidersEntities,\n ...AuthProviderEntities,\n ...ApplicationEntities,\n ...ApplianceEntities,\n ...PrivilegeEntities,\n ...RoleEntities,\n ...UserEntities,\n ...PartnerEntities,\n ...GrantedRoleEntities,\n ...InvitationEntities,\n ...PasswordHistoryEntities,\n ...VerificationTokenEntities,\n ...LoginHistoryEntities,\n ...WebAuthCredentialEntities,\n ...DomainLinkEntities,\n ...DomainOwnerEntities,\n ...AccessRequestEntities\n]\n\nexport const schema = {\n typeDefs: {\n privilegeDirectiveTypeDefs\n },\n\n /* The fields that carry no @privilege, and why — `open-fields.ts`, read by the directive. */\n openFields,\n\n resolverClasses: [\n /* RESOLVER CLASSES */\n ...UsersAuthProvidersResolvers,\n ...AuthProviderResolvers,\n ...ApplicationResolvers,\n ...ApplianceResolvers,\n ...PrivilegeResolvers,\n ...RoleResolvers,\n ...RoleTemplateResolvers,\n ...UserResolvers,\n ...PartnerResolvers,\n ...GrantedRoleResolver,\n ...InvitationResolver,\n ...AppbindingResolver,\n ...DomainGeneratorResolver,\n ...LoginHistoryResolver,\n ...DomainLinkResolver,\n ...DomainOwnerResolvers,\n ...AccessRequestResolvers\n ],\n directives: {\n privilege: privilegeDirectiveResolver\n }\n}\n"]}
|
|
@@ -36,7 +36,8 @@ let InvitationQuery = class InvitationQuery {
|
|
|
36
36
|
const { domain } = context.state;
|
|
37
37
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
38
38
|
domain,
|
|
39
|
-
|
|
39
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
40
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
40
41
|
repository: (0, shell_1.getRepository)(invitation_js_1.Invitation),
|
|
41
42
|
alias: 'invitation',
|
|
42
43
|
searchables: ['email']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invitation-query.js","sourceRoot":"","sources":["../../../server/service/invitation/invitation-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,
|
|
1
|
+
{"version":3,"file":"invitation-query.js","sourceRoot":"","sources":["../../../server/service/invitation/invitation-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,iDAAmH;AAEnH,yEAAiE;AACjE,mDAA4C;AAC5C,+DAAsD;AAEtD;;;;;;;;GAQG;AACH,MAAM,IAAI,GAAG,oGAAoG,CAAA;AAG1G,IAAM,eAAe,GAArB,MAAM,eAAe;IAGpB,AAAN,KAAK,CAAC,UAAU,CAAY,EAAU,EAAS,OAAwB;QACrE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,OAAO,MAAM,IAAA,qBAAa,EAAC,0BAAU,CAAC,CAAC,OAAO,CAAC;YAC7C,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE;YACxC,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC/B,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;OAMG;IAGG,AAAN,KAAK,CAAC,WAAW,CACU,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM;YACN,yGAAyG;YACzG,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,0BAAkB,CAAC,IAAI,EAAE;YACzD,UAAU,EAAE,IAAA,qBAAa,EAAC,0BAAU,CAAC;YACrC,KAAK,EAAE,YAAY;YACnB,WAAW,EAAE,CAAC,OAAO,CAAC;SACvB,CAAC,CAAA;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAED;;;;;;;OAOG;IAEG,AAAN,KAAK,CAAC,KAAK,CAAS,UAAsB;QACxC,OAAO,IAAA,qCAAe,EAAC,UAAU,CAAC,CAAA;IACpC,CAAC;CACF,CAAA;AArDY,0CAAe;AAGpB;IAFL,IAAA,wBAAS,EAAC,IAAI,CAAC;IACf,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,0BAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;IACrF,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;iDAO7C;AAWK;IAFL,IAAA,wBAAS,EAAC,IAAI,CAAC;IACf,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,oCAAc,EAAE,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;IAErF,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;kDAiB3C;AAWK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IACjB,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAa,0BAAU;;4CAEzC;0BApDU,eAAe;IAD3B,IAAA,uBAAQ,EAAC,0BAAU,CAAC;GACR,eAAe,CAqD3B","sourcesContent":["import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { getQueryBuilderFromListParams, InheritedValueType, getRepository, ListParam } from '@things-factory/shell'\n\nimport { invitationState } from '../../utils/invitation-state.js'\nimport { Invitation } from './invitation.js'\nimport { InvitationList } from './invitation-types.js'\n\n/*\n * ── What changed here, and why ──────────────────────────────────────────────\n * These read by `{ email, reference, type }` and took no domain at all — `invitations` did not\n * even take a context, so there was nothing to compare a caller against. An id from one tenant\n * and an id from another were the same kind of argument.\n *\n * They are the invitation **list** now: this domain's invitations, scoped the way every other\n * list in this package is scoped. `reference` is not read; the domain is a column.\n */\nconst GATE = '@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)'\n\n@Resolver(Invitation)\nexport class InvitationQuery {\n @Directive(GATE)\n @Query(returns => Invitation, { nullable: true, description: 'To fetch an invitation of this domain' })\n async invitation(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Invitation> {\n const { domain } = context.state\n\n return await getRepository(Invitation).findOne({\n where: { id, domain: { id: domain.id } },\n relations: ['domain', 'roles']\n })\n }\n\n /**\n * Who was invited to this domain, by whom, when, and whether they came in.\n *\n * ⚠ This is why the rows are kept. Accepting used to delete the row, so the moment somebody\n * joined, the fact that they had been invited stopped existing — there was nothing to put on a\n * screen, so no screen was built, so nothing called any of this.\n */\n @Directive(GATE)\n @Query(returns => InvitationList, { description: \"To fetch this domain's invitations\" })\n async invitations(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<InvitationList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(Invitation),\n alias: 'invitation',\n searchables: ['email']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /**\n * What state this invitation is in, read against the clock.\n *\n * ⚠ Not the stored column on its own. A pending row whose expiry has passed **is** expired\n * whether or not anything has been round to write that down — otherwise the list would show a\n * live invitation for a token that no longer opens anything, which is the more dangerous of\n * the two ways to be wrong here.\n */\n @FieldResolver(type => String)\n async state(@Root() invitation: Invitation): Promise<string> {\n return invitationState(invitation)\n }\n}\n"]}
|
|
@@ -12,11 +12,15 @@ let LoginHistoryQuery = class LoginHistoryQuery {
|
|
|
12
12
|
and it exists precisely because this one should not be open. */
|
|
13
13
|
async loginHistories(params, context) {
|
|
14
14
|
const { domain } = context.state;
|
|
15
|
+
/*
|
|
16
|
+
* The row's domain is `accessDomain` - there is no `domain` column, so handing `domain` to the builder failed every
|
|
17
|
+
* call (no such column). This domain's sign-ins only; `inherited` never widens it to the parent's.
|
|
18
|
+
*/
|
|
15
19
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
20
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
21
|
+
repository: (0, shell_1.getRepository)(login_history_js_1.LoginHistory),
|
|
22
|
+
alias: 'loginHistory'
|
|
23
|
+
}).andWhere('loginHistory.accessDomain = :accessDomainId', { accessDomainId: domain.id });
|
|
20
24
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
21
25
|
return { items, total };
|
|
22
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-history-query.js","sourceRoot":"","sources":["../../../server/service/login-history/login-history-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,
|
|
1
|
+
{"version":3,"file":"login-history-query.js","sourceRoot":"","sources":["../../../server/service/login-history/login-history-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAE9F,iDAA2H;AAE3H,6CAAsC;AACtC,yDAAiD;AACjD,mEAA0D;AAGnD,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B;sEACkE;IAG5D,AAAN,KAAK,CAAC,cAAc,CACO,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC;;;WAGG;QACH,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,0BAAkB,CAAC,IAAI,EAAE;YACzD,UAAU,EAAE,IAAA,qBAAa,EAAC,+BAAY,CAAC;YACvC,KAAK,EAAE,cAAc;SACtB,CAAC,CAAC,QAAQ,CAAC,6CAA6C,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QAEzF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAC3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAGK,AAAN,KAAK,CAAC,gBAAgB,CAAe,KAAa,EAAS,OAAwB;QACjF,MAAM,IAAI,GAAS,OAAO,CAAC,KAAK,CAAC,IAAI,CAAA;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACtC,CAAC;QAED,OAAO,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC;YAC5C,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE;YACtC,IAAI,EAAE,KAAK,IAAI,EAAE;YACjB,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;SAC9B,CAAC,CAAA;IACJ,CAAC;IAGK,AAAN,KAAK,CAAC,YAAY,CAAS,YAA0B;QACnD,OAAO,MAAM,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,cAAc,EAAE,CAAC,CAAA;IACnF,CAAC;IAGK,AAAN,KAAK,CAAC,UAAU,CAAS,YAA0B;QACjD,OAAO,MAAM,IAAA,qBAAa,EAAC,cAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,YAAY,EAAE,CAAC,CAAA;IAC/E,CAAC;CACF,CAAA;AAhDY,8CAAiB;AAKtB;IAFL,IAAA,wBAAS,EAAC,oGAAoG,CAAC;IAC/G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAgB,EAAE,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAErF,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;uDAiB3C;AAGK;IADL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAAY,CAAC,CAAC;IACT,mBAAA,IAAA,kBAAG,EAAC,OAAO,CAAC,CAAA;IAAiB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;yDAWzD;AAGK;IADL,IAAA,4BAAa,GAAE;IACI,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAe,+BAAY;;qDAEpD;AAGK;IADL,IAAA,4BAAa,GAAE;IACE,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAe,+BAAY;;mDAElD;4BA/CU,iBAAiB;IAD7B,IAAA,uBAAQ,EAAC,+BAAY,CAAC;GACV,iBAAiB,CAgD7B","sourcesContent":["import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { Domain, getQueryBuilderFromListParams, InheritedValueType, getRepository, ListParam } from '@things-factory/shell'\n\nimport { User } from '../user/user.js'\nimport { LoginHistory } from './login-history.js'\nimport { LoginHistoryList } from './login-history-type.js'\n\n@Resolver(LoginHistory)\nexport class LoginHistoryQuery {\n /* Everybody's sign-ins. `myLoginHistories` below is the one that answers about the caller,\n and it exists precisely because this one should not be open. */\n @Directive('@privilege(category: \"user\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => LoginHistoryList, { description: 'To fetch multiple LoginHistories' })\n async loginHistories(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<LoginHistoryList> {\n const { domain } = context.state\n\n /*\n * The row's domain is `accessDomain` - there is no `domain` column, so handing `domain` to the builder failed every\n * call (no such column). This domain's sign-ins only; `inherited` never widens it to the parent's.\n */\n const queryBuilder = getQueryBuilderFromListParams({\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(LoginHistory),\n alias: 'loginHistory'\n }).andWhere('loginHistory.accessDomain = :accessDomainId', { accessDomainId: domain.id })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n return { items, total }\n }\n\n @Query(returns => [LoginHistory])\n async myLoginHistories(@Arg('limit') limit: number, @Ctx() context: ResolverContext): Promise<LoginHistory[]> {\n const user: User = context.state.user\n if (!user) {\n throw new Error('No user specified')\n }\n\n return await getRepository(LoginHistory).find({\n where: { accessUser: { id: user.id } },\n take: limit || 10,\n order: { accessedAt: 'DESC' }\n })\n }\n\n @FieldResolver()\n async accessDomain(@Root() loginHistory: LoginHistory) {\n return await getRepository(Domain).findOneBy({ id: loginHistory.accessDomainId })\n }\n\n @FieldResolver()\n async accessUser(@Root() loginHistory: LoginHistory) {\n return await getRepository(User).findOneBy({ id: loginHistory.accessUserId })\n }\n}\n"]}
|
|
@@ -14,7 +14,8 @@ let PartnerQuery = class PartnerQuery {
|
|
|
14
14
|
const { domain } = context.state;
|
|
15
15
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
16
16
|
domain,
|
|
17
|
-
|
|
17
|
+
// this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent
|
|
18
|
+
params: { ...params, inherited: shell_1.InheritedValueType.None },
|
|
18
19
|
repository: (0, shell_1.getRepository)(partner_js_1.Partner),
|
|
19
20
|
alias: 'partner'
|
|
20
21
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner-query.js","sourceRoot":"","sources":["../../../server/service/partner/partner-query.ts"],"names":[],"mappings":";;;;AAAA,+CAAyF;AAGzF,
|
|
1
|
+
{"version":3,"file":"partner-query.js","sourceRoot":"","sources":["../../../server/service/partner/partner-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'\nimport { SelectQueryBuilder } from 'typeorm'\n\nimport { Domain, DomainList, getRepository, ListParam, getQueryBuilderFromListParams, InheritedValueType } from '@things-factory/shell'\n\nimport { checkUserBelongsDomain } from '../../utils/check-user-belongs-domain.js'\nimport { User } from '../user/user.js'\nimport { Partner } from './partner.js'\nimport { PartnerList } from './partner-types.js'\n\n@Resolver(Partner)\nexport class PartnerQuery {\n @Directive('@privilege(category: \"partner\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => PartnerList)\n async partners(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<PartnerList> {\n if (await checkUserBelongsDomain(context.state.domain, context.state.user)) {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n // this domain's rows only - a parent domain's are another tenant's, whatever `inherited` the caller sent\n params: { ...params, inherited: InheritedValueType.None },\n repository: getRepository(Partner),\n alias: 'partner'\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n } else {\n throw new Error(`User doesn't belong in current domain`)\n }\n }\n\n @Directive('@privilege(category: \"partner\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => [Domain])\n async customers(@Ctx() context: ResolverContext): Promise<Domain[]> {\n const { domain } = context.state\n const partners: Partner[] = await getRepository(Partner).find({\n where: { domain: { id: domain.id } },\n relations: ['partnerDomain']\n })\n\n return partners.map((p: Partner) => p.partnerDomain)\n }\n\n @Directive('@privilege(category: \"partner\", privilege: \"query\")')\n @Query(returns => DomainList)\n async searchCustomers(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<DomainList> {\n const { domain } = context.state\n const partners: Partner[] = await getRepository(Partner).find({\n where: { domain: { id: domain.id } },\n relations: ['partnerDomain']\n })\n\n const qb: SelectQueryBuilder<Domain> = await getQueryBuilderFromListParams({\n repository: getRepository(Domain),\n params,\n searchables: ['name', 'description']\n })\n\n qb.andWhereInIds(partners.map((p: Partner) => p.partnerDomain.id))\n const [items, total] = await qb.getManyAndCount()\n return { items, total }\n }\n\n @Directive('@privilege(category: \"partner\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => [Domain])\n async vendors(@Ctx() context: ResolverContext): Promise<Domain[]> {\n const { domain } = context.state\n const qb: SelectQueryBuilder<Partner> = getRepository(Partner).createQueryBuilder('PARTNER')\n const partners: Partner[] = await qb\n .leftJoinAndSelect('PARTNER.domain', 'DOMAIN')\n .leftJoinAndSelect('PARTNER.partnerDomain', 'P_DOMAIN')\n .where('P_DOMAIN.id = :domainId', { domainId: domain.id })\n .getMany()\n\n return partners.map((p: Partner) => p.domain)\n }\n\n @FieldResolver()\n async domain(@Root() partner: Partner) {\n return await getRepository(Domain).findOneBy({ id: partner.domainId })\n }\n\n @FieldResolver()\n async partnerDomain(@Root() partner: Partner) {\n return await getRepository(Domain).findOneBy({ id: partner.partnerDomainId })\n }\n\n @FieldResolver()\n async requester(@Root() partner: Partner) {\n return await getRepository(User).findOneBy({ id: partner.requesterId })\n }\n\n @FieldResolver()\n async approver(@Root() partner: Partner) {\n return await getRepository(User).findOneBy({ id: partner.approverId })\n }\n}\n"]}
|