Skip to content

ATS-PFM-SEC-008Offer and manage an invitation: Capability Test Specification

Markdown

ATS-PFM-SEC-008

Offer and manage an invitation: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaPlatformModuleSecurity, Customers and WorkspacesRevision2

Read atservices-platform ad3f6a65react-console baf6dae3

Coverage

  • Rule gap: FND-PFM-SEC-065
  • Transition covered
  • Validation covered
  • Permission covered
  • Edge gap: FND-PFM-SEC-065
  • Failure covered
  • Boundary covered
  • Concurrency gap: FND-PFM-SEC-065
  • Invariant covered
  • Interaction covered

Test Scenarios

22 scenarios proving CAP-PFM-SEC-008; 11 bound to an existing test.

01 Check invitation customer boundariesboundaryapinegativetest
Proves
BR-CAP-PFM-SEC-008-01
Preconditions
Prepare two customers with memberships.
Steps
Invite into the other customer and act on its member and on a missing identity.
Expected
Out-of-boundary and missing cases return 404 without creating a person; public acceptance endpoints declare no permission.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses an invitation into a customer the caller does not reach, as 404, and leaves nothing behind
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses to act on a user outside the caller's scope and an unknown one, telling the two apart for nobody
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#declares the lifecycle routes with the one permission that gives access, and the public ones with none
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses an invitation into a customer the caller does not reach, as 404, and leaves nothing behind
02 Check address requirements and normalizationvalidationunitnegativetest
Proves
BR-CAP-PFM-SEC-008-02
Preconditions
Prepare otherwise valid invitation input.
Steps
Try missing, invalid and mixed-case addresses.
Expected
Missing and invalid addresses fail without creation; the accepted address is stored canonically.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses an invalid e-mail address as ObjectInvalid naming email_address, creating nobody
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses an invitation with no e-mail address, because nothing could ever be delivered
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#invites the person under the canonical form of the address it was given
Source
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses an invalid e-mail address as ObjectInvalid naming email_address, creating nobody
03 Check duplicate and returning membershipstransitionapinegativetest
Proves
BR-CAP-PFM-SEC-008-03
Preconditions
Prepare active, invited and revoked members.
Steps
Invite each identity again.
Expected
Active and invited members receive their respective existing-member codes and guidance; the revoked member reuses the existing record.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses an invitation to somebody who has already accepted, pointing at their roles instead
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a second invitation to somebody already invited here, telling the administrator to resend
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#invites a revoked member back onto the row and the account they already had
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses an invitation to somebody who has already accepted, pointing at their roles instead
04 Check committed records survive delivery failurefailureapitest
Proves
BR-CAP-PFM-SEC-008-04
Preconditions
Prepare a taken sign-in alias and a failing mail provider.
Steps
Invite in both conditions, then restore the provider and resend.
Expected
Delivery reports refusal or failure and its reason without exposing a token; committed records persist and resend can deliver.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#creates the user, provisions the account and e-mails the token in the request, answering that it was sent and no token
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#creates the user, provisions the account and e-mails the token in the request, answering that it was sent and no token
05 Check role delegation and self-invitationpermissionapinegativetest
Proves
BR-CAP-PFM-SEC-008-05
Preconditions
Prepare an inviter allowed a limited set of permissions.
Steps
Offer an allowed role, a role exceeding those permissions and a role to the inviter’s own account.
Expected
The allowed offer succeeds; excessive delegation names missing keys and self-invitation fails.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#lets a caller grant a role whose every key they are allowed where they are granting it
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a role that grants more than the caller may do there, and names what was missing
services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#refuses a caller granting to their own user, whatever they hold
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#lets a caller grant a role whose every key they are allowed where they are granting it
06 Check pending access and membership scopeinvariantapinegativetest
Proves
BR-CAP-PFM-SEC-008-06
Preconditions
Prepare an invited membership.
Steps
Read context before acceptance and offer grants outside the customer or beyond a portal member’s workspace.
Expected
Pre-acceptance access is refused and invalid grant boundaries fail before a new member is created.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses the seeded invited user every signed request until it accepts
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses a grant that reaches outside the wall the user is being created in, before a user exists
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses a member's grant that is not tenant-scoped, or names another tenant
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a grant that reaches outside the wall the user is being created in
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses the seeded invited user every signed request until it accepts
07 Check resend invalidates the preceding linktransitionapinegativetest
Proves
BR-CAP-PFM-SEC-008-07 INV-DOM-PFM-SEC-003-03
Preconditions
Prepare invited and accepted memberships.
Steps
Resend each invitation.
Expected
The invited member receives a new usable link and the old link fails; the accepted member receives recovery guidance.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#supersedes the old token on a resend, so only the newest link works
services-platform:modules/security/tests/unit/services/invitations/resend-invitation.spec.js#refuses an account that has already accepted, telling the administrator to reset the password instead
react-console:e2e/security/invitations.spec.ts#resending from the console invalidates the link it replaces
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#supersedes the old token on a resend, so only the newest link works
08 Check withdrawal prevents acceptancetransitionapinegativetest
Proves
BR-CAP-PFM-SEC-008-08
Preconditions
Prepare a member with an outstanding link.
Steps
Withdraw membership and attempt to use the link.
Expected
Acceptance fails and cannot restore the revoked membership.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#revoking a membership stops the link already in the inbox, and the account cannot come back by accepting it
react-console:e2e/security/invitations.spec.ts#revoking from the console withdraws the link
react-console:e2e/dev/invitations.dev.spec.ts#says an invitation was withdrawn when the administrator revoked it
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#revoking a membership stops the link already in the inbox, and the account cannot come back by accepting it
09 Check direct activation prerequisitesvalidationapinegativetest
Proves
BR-CAP-PFM-SEC-008-10
Preconditions
Prepare never-invited linked and currently invited memberships.
Steps
Request activation for both.
Expected
The linked never-invited membership activates and can read its own record; the invited membership is refused.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#links the identity from the pool, activates without an invitation, and the user then reaches GET /users/me
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses to activate a user with an invitation in flight (the person accepts it, or has it resent), and one outside the scope
services-platform:modules/security/tests/unit/services/invitations/activate-user.spec.js#refuses a user that was invited (accept or resend instead), an unprovisioned one and a disabled one, writing nothing
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#links the identity from the pool, activates without an invitation, and the user then reaches GET /users/me
10 Check safe invitation-message renderingvalidationunitnegativetest
Proves
BR-CAP-PFM-SEC-008-12
Preconditions
Prepare display-name markup and newline inputs.
Steps
Render the invitation message.
Expected
The HTML escapes injected markup, From stays on one line, the subject omits the token and the available expiry appears in the body.
Data
Use the records described in the setup.
Bound to
services-platform:modules/security/tests/unit/services/invitations/invitation-email.spec.js#lets no raw angle bracket of the display name reach the HTML body
services-platform:modules/security/tests/unit/services/invitations/invitation-email.spec.js#strips the quote and the newline of an injected display name, leaving one header line
services-platform:modules/security/tests/unit/services/invitations/invitation-email.spec.js#names the expiry date in the text body when the invitation has one
Source
services-platform:modules/security/tests/unit/services/invitations/invitation-email.spec.js#lets no raw angle bracket of the display name reach the HTML body
11 Check invitation actions from the user listinteractionbrowsertest
Proves
AS-JNY-PFM-SEC-003-01
Preconditions
Sign in as a security administrator.
Steps
Invite a colleague, select the Invited filter and use resend and revoke row actions.
Expected
The new row shows Invited and the two management actions update the invitation state.
Data
Use the records described in the setup.
Bound to
react-console:e2e/security/invitations.spec.ts#invites a new identity from the Users screen
react-console:e2e/mock/security-admin.mock.spec.ts#a new invitation appears in the list as Invited
react-console:e2e/mock/security-admin.mock.spec.ts#resends and revokes an invitation from a row's actions
Source
react-console:e2e/security/invitations.spec.ts#invites a new identity from the Users screen
12 Membership status: invited to activetransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-10
Preconditions
Use an isolated membership status in invited state, with the required authority and guard fixtures.
Steps
[ { "do": "Directly activate a linked invited member that has never received an invitation.", "expect": "Read the resulting membership status as active; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/activate-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as active; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/activate-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
13 Membership status: invited to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-08
Preconditions
Use an isolated membership status in invited state, with the required authority and guard fixtures.
Steps
[ { "do": "Withdraw the invited membership and inspect its offered assignments and removal work.", "expect": "Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/revoke-user.ts", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as revoked; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/revoke-user.ts,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
14 Membership status: revoked to invitedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-03
Preconditions
Use an isolated membership status in revoked state, with the required authority and guard fixtures.
Steps
[ { "do": "Invite the revoked address again and compare membership identity and invitation identity.", "expect": "Read the resulting membership status as invited; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/users.ts:reinviteRevokedUser", "services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts." ] } ]
Expected
Read the resulting membership status as invited; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/users.ts:reinviteRevokedUser,services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts, activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts; services/membership/lockout.ts, last-administrator.ts.
15 Invitation: issued to livetransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-04
Preconditions
Use an isolated invitation in issued state, with the required authority and guard fixtures.
Steps
[ { "do": "Prepare the provider account and issue the invitation token before delivery.", "expect": "Read the resulting invitation as live; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/invitations.ts:issueInvitationToken", "services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts." ] } ]
Expected
Read the resulting invitation as live; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/invitations.ts:issueInvitationToken,services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts.
16 Invitation: live to supersededtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-07
Preconditions
Use an isolated invitation in live state, with the required authority and guard fixtures.
Steps
[ { "do": "Resend the invitation and attempt to use the replaced link.", "expect": "Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/invitations.ts:supersedeOutstandingInvitations", "services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts." ] } ]
Expected
Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/invitations.ts:supersedeOutstandingInvitations,services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts.
17 Invitation: expired to supersededtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-07
Preconditions
Use an isolated invitation in expired state, with the required authority and guard fixtures.
Steps
[ { "do": "Replace the expired invitation and compare the new validity window.", "expect": "Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/resend-invitation.ts", "services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts." ] } ]
Expected
Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/resend-invitation.ts,services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts.
18 Invitation: issued to supersededtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-07
Preconditions
Use an isolated invitation in issued state, with the required authority and guard fixtures.
Steps
[ { "do": "Resend an invitation whose provider preparation has not yet produced a token.", "expect": "Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/invitations/resend-invitation.ts", "services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts." ] } ]
Expected
Read the resulting invitation as superseded; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/invitations/resend-invitation.ts,services-platform at ad3f6a65: modules/security/db/user-invitations.table.ts; services/persistence/invitations.ts; services/invitations/invitation-lifetime.ts, resend-invitation.ts, accept-invitation.ts; services/provisioning/provision-user.ts.
19 Role assignment: pending to revokedtransitionapiproposed
Proves
BR-CAP-PFM-SEC-008-08
Preconditions
Use an isolated role assignment in pending state, with the required authority and guard fixtures.
Steps
[ { "do": "Withdraw the invitation and inspect the pending assignment’s retained row.", "expect": "Read the resulting role assignment as revoked; inspect the associated records and recorded history for this transition.", "provenance": "proposed", "source": [ "services-platform:modules/security/services/persistence/assignments.ts:revokeAssignmentsOfUser", "services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts." ] } ]
Expected
Read the resulting role assignment as revoked; inspect the associated records and recorded history for this transition.
Data
A disposable customer, workspace and named actor; a controllable clock where the transition depends on time.
Source
services-platform:modules/security/services/persistence/assignments.ts:revokeAssignmentsOfUser,services-platform at ad3f6a65: modules/security/db/security-assignments.table.ts; services/persistence/assignments.ts; services/membership/manage-assignments.ts; services/invitations/widening.ts.
20 Offer and manage an invitation with join through an invitationinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-005-03 BR-CAP-PFM-SEC-008-07
Preconditions
An invited person retains the first invitation link.
Steps
Resend the invitation, attempt acceptance through the old link, then accept through the replacement.
Expected
The old link is superseded; only the replacement activates the membership.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/unit/services/invitations/accept-invitation.spec.js#answers an expired, a revoked and a superseded token with the same sentence, and records which it was,services-platform:modules/security/tests/unit/services/invitations/resend-invitation.spec.js#supersedes the outstanding invitations and issues a new one with a new token, in one transaction
21 Offer and manage an invitation with maintain console membershipsinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-008-03 BR-CAP-PFM-SEC-009-05
Preconditions
A console member has a pending invitation and offered assignments.
Steps
Revoke the membership, inspect the old offer, and invite the same address again.
Expected
The old offer cannot activate access; reinvitation reuses membership identity with a new offer.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/unit/services/invitations/invite-user.spec.js#refuses somebody already invited to that wall as already_invited, telling the administrator to resend,services-platform:modules/security/services/invitations/suspend-user.ts:reinstateUser
22 Offer and manage an invitation with assign roles within a controlled scopeinteractionapinegativeproposed
Proves
BR-CAP-PFM-SEC-008-05 BR-CAP-PFM-SEC-010-02
Preconditions
An access manager can delegate one role but lacks another role’s powers.
Steps
Invite with the permitted role, then attempt another invitation carrying the unavailable role.
Expected
The first creates pending assignments; the second creates neither invitation nor assignment.
Data
An isolated customer with two workspaces, ordinary and staff identities, and records owned by this run.
Source
services-platform:modules/security/tests/e2e/invitations.e2e.spec.js#refuses a role that grants more than the caller may do there, and names what was missing,services-platform:modules/security/tests/unit/services/invitations/widening.spec.ts#refuses a scope the caller does not manage, and says which scope rather than which role

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.