@@ -88,7 +88,8 @@ async function resolveIssueContext({ input }: { input: IssueInput }): Promise<Is
8888 return { ...workspace , issue : row }
8989}
9090
91- const authorizeIssues = ( { context } : { context : ActiveWorkspaceApplicationContext } ) =>
91+ /** Called from an unannotated `authorizeResource` arrow, so it never narrows the inferred context. */
92+ const authorizeIssues = ( context : { workspaceOrganizationId : string | null } ) =>
9293 requireIssuesEnabled ( context . workspaceOrganizationId )
9394
9495function validateTitle ( title : string ) : string {
@@ -169,7 +170,7 @@ export const listIssues = defineAuthorizedWorkspaceUseCase({
169170 resolveContext : ( { input } : { input : { workspaceId : string } } ) =>
170171 resolveActiveWorkspaceApplicationContext ( input . workspaceId ) ,
171172 authorizationOptions,
172- authorizeResource : authorizeIssues ,
173+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
173174 async execute ( { context } ) {
174175 const rows = await listWorkspaceIssues ( context . workspaceId )
175176 return { issues : await presentRows ( rows ) }
@@ -180,7 +181,7 @@ export const getIssueDetail = defineAuthorizedWorkspaceUseCase({
180181 operation : issueOperations . read ,
181182 resolveContext : resolveIssueContext ,
182183 authorizationOptions,
183- authorizeResource : authorizeIssues ,
184+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
184185 async execute ( { context } ) {
185186 const issueId = context . issue . id
186187 const [ issue , events , chats , resources , tickets ] = await Promise . all ( [
@@ -219,7 +220,7 @@ export const createIssue = defineAuthorizedWorkspaceUseCase({
219220 resolveContext : ( { input } : { input : CreateIssueInput } ) =>
220221 resolveActiveWorkspaceApplicationContext ( input . workspaceId ) ,
221222 authorizationOptions,
222- authorizeResource : authorizeIssues ,
223+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
223224 async execute ( { input, context, principal } ) {
224225 const title = validateTitle ( input . title )
225226 if ( Buffer . byteLength ( input . body , 'utf-8' ) > MAX_BODY_BYTES )
@@ -283,7 +284,7 @@ export const updateIssue = defineAuthorizedWorkspaceUseCase({
283284 operation : issueOperations . update ,
284285 resolveContext : ( { input } : { input : UpdateIssueInput } ) => resolveIssueContext ( { input } ) ,
285286 authorizationOptions,
286- authorizeResource : authorizeIssues ,
287+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
287288 async execute ( { input, context, principal } ) {
288289 const current = context . issue
289290 const values : Partial < IssueRow > = { }
@@ -330,7 +331,7 @@ export const startIssue = defineAuthorizedWorkspaceUseCase({
330331 resolveContext : ( { input } : { input : IssueInput & { chatId : string } } ) =>
331332 resolveIssueContext ( { input } ) ,
332333 authorizationOptions,
333- authorizeResource : authorizeIssues ,
334+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
334335 async execute ( { input, context, principal } ) {
335336 const userId = requirePrincipalSubjectUserId ( principal )
336337 const chat = await getUserWorkspaceChat ( db , input . chatId , context . workspaceId , userId )
@@ -363,7 +364,7 @@ export const requestIssueReview = defineAuthorizedWorkspaceUseCase({
363364 resolveContext : ( { input } : { input : IssueInput & { summary : string } } ) =>
364365 resolveIssueContext ( { input } ) ,
365366 authorizationOptions,
366- authorizeResource : authorizeIssues ,
367+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
367368 async execute ( { input, context, principal } ) {
368369 const summary = input . summary . trim ( )
369370 if ( ! summary ) throw new OrchestrationError ( 'validation' , 'Say what changed for the reviewer' )
@@ -388,7 +389,7 @@ export const approveIssue = defineAuthorizedWorkspaceUseCase({
388389 operation : issueOperations . review ,
389390 resolveContext : resolveIssueContext ,
390391 authorizationOptions,
391- authorizeResource : authorizeIssues ,
392+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
392393 async execute ( { context, principal } ) {
393394 await transition (
394395 context . issue . id ,
@@ -408,7 +409,7 @@ export const requestIssueChanges = defineAuthorizedWorkspaceUseCase({
408409 resolveContext : ( { input } : { input : IssueInput & { note ?: string } } ) =>
409410 resolveIssueContext ( { input } ) ,
410411 authorizationOptions,
411- authorizeResource : authorizeIssues ,
412+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
412413 async execute ( { input, context, principal } ) {
413414 const note = input . note ?. trim ( ) || null
414415 await transition (
@@ -433,7 +434,7 @@ export const closeIssue = defineAuthorizedWorkspaceUseCase({
433434 operation : issueOperations . close ,
434435 resolveContext : ( { input } : { input : CloseIssueInput } ) => resolveIssueContext ( { input } ) ,
435436 authorizationOptions,
436- authorizeResource : authorizeIssues ,
437+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
437438 async execute ( { input, context, principal } ) {
438439 let duplicateOf : IssueRow | null = null
439440 if ( input . reason === 'duplicate' ) {
@@ -474,7 +475,7 @@ export const reopenIssue = defineAuthorizedWorkspaceUseCase({
474475 operation : issueOperations . close ,
475476 resolveContext : resolveIssueContext ,
476477 authorizationOptions,
477- authorizeResource : authorizeIssues ,
478+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
478479 async execute ( { context, principal } ) {
479480 await transition (
480481 context . issue . id ,
@@ -504,7 +505,7 @@ export const addIssueResource = defineAuthorizedWorkspaceUseCase({
504505 operation : issueOperations . update ,
505506 resolveContext : ( { input } : { input : IssueResourceInput } ) => resolveIssueContext ( { input } ) ,
506507 authorizationOptions,
507- authorizeResource : authorizeIssues ,
508+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
508509 async execute ( { input, context, principal } ) {
509510 await db . transaction ( async ( tx ) => {
510511 const added = await insertIssueResourceInTx (
@@ -528,7 +529,7 @@ export const removeIssueResource = defineAuthorizedWorkspaceUseCase({
528529 operation : issueOperations . update ,
529530 resolveContext : ( { input } : { input : IssueResourceInput } ) => resolveIssueContext ( { input } ) ,
530531 authorizationOptions,
531- authorizeResource : authorizeIssues ,
532+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
532533 async execute ( { input, context, principal } ) {
533534 await db . transaction ( async ( tx ) => {
534535 const removed = await deleteIssueResourceInTx (
@@ -553,7 +554,7 @@ export const linkIssueTicket = defineAuthorizedWorkspaceUseCase({
553554 resolveContext : ( { input } : { input : IssueInput & { ticket : IssueTicketInsert } } ) =>
554555 resolveIssueContext ( { input } ) ,
555556 authorizationOptions,
556- authorizeResource : authorizeIssues ,
557+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
557558 async execute ( { input, context, principal } ) {
558559 await db . transaction ( async ( tx ) => {
559560 const linked = await insertIssueTicketInTx ( tx , context . issue . id , input . ticket )
@@ -573,7 +574,7 @@ export const unlinkIssueTicket = defineAuthorizedWorkspaceUseCase({
573574 resolveContext : ( { input } : { input : IssueInput & { ticketId : string } } ) =>
574575 resolveIssueContext ( { input } ) ,
575576 authorizationOptions,
576- authorizeResource : authorizeIssues ,
577+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
577578 async execute ( { input, context, principal } ) {
578579 await db . transaction ( async ( tx ) => {
579580 const unlinked = await deleteIssueTicketInTx ( tx , context . issue . id , input . ticketId )
@@ -596,7 +597,7 @@ export const addIssueComment = defineAuthorizedWorkspaceUseCase({
596597 resolveContext : ( { input } : { input : IssueInput & { body : string } } ) =>
597598 resolveIssueContext ( { input } ) ,
598599 authorizationOptions,
599- authorizeResource : authorizeIssues ,
600+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
600601 async execute ( { input, context, principal } ) {
601602 const body = input . body . trim ( )
602603 if ( ! body ) throw new OrchestrationError ( 'validation' , 'A comment cannot be empty' )
@@ -620,7 +621,7 @@ export const deleteIssueComment = defineAuthorizedWorkspaceUseCase({
620621 resolveContext : ( { input } : { input : IssueInput & { commentId : string } } ) =>
621622 resolveIssueContext ( { input } ) ,
622623 authorizationOptions,
623- authorizeResource : authorizeIssues ,
624+ authorizeResource : ( { context } ) => authorizeIssues ( context ) ,
624625 async execute ( { input, context, principal } ) {
625626 const userId = requirePrincipalSubjectUserId ( principal )
626627 const deleted = await db . transaction ( ( tx ) =>
0 commit comments