11import { assertNonNullish } from 'testkit/utils' ;
2+ import { PersonalAccessTokensCache } from '../../../packages/services/api/src/modules/organization/providers/personal-access-tokens-cache' ;
23import { graphql } from '../../testkit/gql' ;
34import * as GraphQLSchema from '../../testkit/gql/graphql' ;
45import { execute } from '../../testkit/graphql' ;
@@ -299,7 +300,8 @@ test.concurrent('query GraphQL API on resources with access', async ({ expect })
299300 authToken : ownerToken ,
300301 } ) . then ( e => e . expectNoGraphQLErrors ( ) ) ;
301302 expect ( result . createPersonalAccessToken . error ) . toEqual ( null ) ;
302- const organizationAccessToken = result . createPersonalAccessToken . ok ! . privateAccessKey ;
303+ assertNonNullish ( result . createPersonalAccessToken . ok ) ;
304+ const personalAccessToken = result . createPersonalAccessToken . ok . privateAccessKey ;
303305
304306 const projectQuery = await execute ( {
305307 document : OrganizationProjectTargetQuery1 ,
@@ -308,7 +310,7 @@ test.concurrent('query GraphQL API on resources with access', async ({ expect })
308310 projectSlug : project . project . slug ,
309311 targetSlug : project . target . slug ,
310312 } ,
311- authToken : organizationAccessToken ,
313+ authToken : personalAccessToken ,
312314 } ) . then ( e => e . expectNoGraphQLErrors ( ) ) ;
313315 expect ( projectQuery ) . toEqual ( {
314316 organization : {
@@ -376,3 +378,107 @@ test.concurrent('query GraphQL API on resources without access', async ({ expect
376378 } ,
377379 } ) ;
378380} ) ;
381+
382+ test . concurrent (
383+ 'query GraphQL API after membership resources have been downgraded' ,
384+ async ( { expect } ) => {
385+ const seed = await initSeed ( ) ;
386+ const { createOrg } = await seed . createOwner ( ) ;
387+ const org = await createOrg ( ) ;
388+ const project = await org . createProject ( GraphQLSchema . ProjectType . Federation ) ;
389+
390+ const { member, memberToken, assignMemberRole, createMemberRole } =
391+ await org . inviteAndJoinMember ( ) ;
392+
393+ const newRole = await createMemberRole ( [
394+ 'organization:describe' ,
395+ 'project:describe' ,
396+ 'personalAccessToken:modify' ,
397+ ] ) ;
398+
399+ // make user also an admin
400+ await assignMemberRole ( {
401+ userId : member . id ,
402+ roleId : newRole . id ,
403+ } ) ;
404+
405+ const result = await execute ( {
406+ document : CreatePersonalAccessTokenMutation ,
407+ variables : {
408+ input : {
409+ organization : {
410+ byId : org . organization . id ,
411+ } ,
412+ title : 'a access token' ,
413+ description : 'a description' ,
414+ resources : { mode : GraphQLSchema . ResourceAssignmentModeType . All } ,
415+ permissions : [ 'organization:describe' , 'project:describe' ] ,
416+ } ,
417+ } ,
418+ authToken : memberToken ,
419+ } ) . then ( e => e . expectNoGraphQLErrors ( ) ) ;
420+
421+ expect ( result . createPersonalAccessToken . error ) . toEqual ( null ) ;
422+ assertNonNullish ( result . createPersonalAccessToken . ok ) ;
423+
424+ const personalAccessToken = result . createPersonalAccessToken . ok . privateAccessKey ;
425+
426+ let projectQuery = await execute ( {
427+ document : OrganizationProjectTargetQuery1 ,
428+ variables : {
429+ organizationSlug : org . organization . slug ,
430+ projectSlug : project . project . slug ,
431+ targetSlug : project . target . slug ,
432+ } ,
433+ authToken : personalAccessToken ,
434+ } ) . then ( e => e . expectNoGraphQLErrors ( ) ) ;
435+
436+ expect ( projectQuery ) . toEqual ( {
437+ organization : {
438+ id : org . organization . id ,
439+ project : {
440+ id : project . project . id ,
441+ slug : project . project . slug ,
442+ targetBySlug : {
443+ id : project . target . id ,
444+ slug : project . target . slug ,
445+ } ,
446+ } ,
447+ slug : org . organization . slug ,
448+ } ,
449+ } ) ;
450+
451+ // Update member role assignment so it looses access to describe project/target on the resources
452+ await assignMemberRole ( {
453+ userId : member . id ,
454+ roleId : newRole . id ,
455+ resources : {
456+ mode : GraphQLSchema . ResourceAssignmentModeType . Granular ,
457+ projects : [ ] ,
458+ } ,
459+ } ) ;
460+
461+ // simulate 5 minutes passing by...
462+ await seed . purgePersonalAccessTokenById (
463+ result . createPersonalAccessToken . ok . createdPersonalAccessToken . id ,
464+ ) ;
465+
466+ projectQuery = await execute ( {
467+ document : OrganizationProjectTargetQuery1 ,
468+ variables : {
469+ organizationSlug : org . organization . slug ,
470+ projectSlug : project . project . slug ,
471+ targetSlug : project . target . slug ,
472+ } ,
473+ authToken : personalAccessToken ,
474+ } ) . then ( e => e . expectNoGraphQLErrors ( ) ) ;
475+
476+ expect ( projectQuery ) . toEqual ( {
477+ organization : {
478+ id : org . organization . id ,
479+ project : null ,
480+ slug : org . organization . slug ,
481+ } ,
482+ } ) ;
483+ } ,
484+ ) ;
0 commit comments