Update graphql schema

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-13 10:07:52 +04:00
parent 108e9cb85d
commit c115e2c9dc
23 changed files with 2259 additions and 2749 deletions

View File

@@ -138,13 +138,13 @@ type Identity implements Node {
createdAt: Datetime!
updatedAt: Datetime!
memberships(
profiles(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: MembershipOrder
): MembershipConnection @goField(forceResolver: true)
orderBy: ProfileOrder
): ProfileConnection @goField(forceResolver: true)
pendingInvitations(
first: Int
@@ -178,7 +178,7 @@ type Identity implements Node {
@session(required: PRESENT)
}
type MembershipProfile implements Node {
type Profile implements Node {
id: ID!
fullName: String!
additionalEmailAddresses: [EmailAddr!]!
@@ -191,9 +191,7 @@ type MembershipProfile implements Node {
identity: Identity @goField(forceResolver: true)
organization: Organization @goField(forceResolver: true)
# FIXME: remove when memberships are under profile
membershipId: ID!
membership: Membership @goField(forceResolver: true)
permission(action: String!): Boolean!
@goField(forceResolver: true)
@@ -212,13 +210,13 @@ type Organization implements Node {
createdAt: Datetime!
updatedAt: Datetime!
members(
profiles(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: MembershipOrder
): MembershipConnection @goField(forceResolver: true)
orderBy: ProfileOrder
): ProfileConnection @goField(forceResolver: true)
invitations(
first: Int
@@ -238,7 +236,7 @@ type Organization implements Node {
scimConfiguration: SCIMConfiguration @goField(forceResolver: true)
viewerMembership: Membership @goField(forceResolver: true)
viewer: Profile @goField(forceResolver: true)
permission(action: String!): Boolean!
@goField(forceResolver: true)
@@ -285,9 +283,6 @@ enum MembershipState
type Membership implements Node {
id: ID!
createdAt: Datetime!
identity: Identity @goField(forceResolver: true)
profile: MembershipProfile @goField(forceResolver: true)
organization: Organization @goField(forceResolver: true)
role: MembershipRole!
source: MembershipSource!
state: MembershipState!
@@ -445,7 +440,7 @@ type SCIMEvent implements Node {
requestBody: String
responseBody: String
errorMessage: String
membership: Membership @goField(forceResolver: true)
profile: Profile @goField(forceResolver: true)
ipAddress: String!
createdAt: Datetime!
@@ -483,50 +478,6 @@ enum ReauthenticationReason {
POLICY_REQUIREMENT
}
enum MembershipOrderField
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipOrderField") {
FULL_NAME
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldFullName"
)
ORGANIZATION_NAME
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldOrganizationName"
)
EMAIL_ADDRESS
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldEmailAddress"
)
ROLE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldRole")
CREATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldCreatedAt"
)
}
input MembershipOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.MembershipOrderBy"
) {
direction: OrderDirection!
field: MembershipOrderField!
}
type MembershipConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.MembershipConnection"
) {
edges: [MembershipEdge!]!
pageInfo: PageInfo!
totalCount: Int @goField(forceResolver: true)
}
type MembershipEdge {
node: Membership!
cursor: CursorKey!
}
enum InvitationOrderField
@goModel(model: "go.probo.inc/probo/pkg/coredata.InvitationOrderField") {
FULL_NAME
@@ -573,6 +524,45 @@ type InvitationEdge {
cursor: CursorKey!
}
enum ProfileOrderField
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderField") {
FULL_NAME
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldFullName"
)
CREATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldCreatedAt"
)
KIND @goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldKind")
ORGANIZATION_NAME
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldOrganizationName"
)
}
input ProfileOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.ProfileOrderBy"
) {
direction: OrderDirection!
field: ProfileOrderField!
}
type ProfileConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.ProfileConnection"
) {
totalCount: Int @goField(forceResolver: true)
edges: [ProfileEdge!]!
pageInfo: PageInfo!
}
type ProfileEdge {
cursor: CursorKey!
node: Profile!
}
type SessionConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.SessionConnection"
@@ -885,7 +875,7 @@ type RevokePersonalAPIKeyPayload {
type CreateOrganizationPayload {
organization: Organization
membershipEdge: MembershipEdge!
membership: Membership!
}
type UpdateOrganizationPayload {
@@ -905,7 +895,7 @@ type InviteMemberPayload {
}
type UpdateProfilePayload {
profile: MembershipProfile!
profile: Profile!
}
type UpdateMembershipPayload {
@@ -917,7 +907,7 @@ type RemoveMemberPayload {
}
type AcceptInvitationPayload {
membershipEdge: MembershipEdge!
membership: Membership!
invitation: Invitation!
}

File diff suppressed because it is too large Load Diff

View File

@@ -16,61 +16,14 @@ package types
import (
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/gid"
"go.probo.inc/probo/pkg/page"
)
type (
MembershipOrderBy OrderBy[coredata.MembershipOrderField]
MembershipConnection struct {
TotalCount int
Edges []*MembershipEdge
PageInfo PageInfo
Resolver any
ParentID gid.GID
}
)
func NewMembershipConnection(
p *page.Page[*coredata.Membership, coredata.MembershipOrderField],
resolver any,
parentID gid.GID,
) *MembershipConnection {
edges := make([]*MembershipEdge, len(p.Data))
for i, membership := range p.Data {
edges[i] = NewMembershipEdge(membership, p.Cursor.OrderBy.Field)
}
return &MembershipConnection{
Edges: edges,
PageInfo: *NewPageInfo(p),
Resolver: resolver,
ParentID: parentID,
}
}
func NewMembershipEdge(membership *coredata.Membership, orderField coredata.MembershipOrderField) *MembershipEdge {
return &MembershipEdge{
Node: NewMembership(membership),
Cursor: membership.CursorKey(orderField),
}
}
func NewMembership(membership *coredata.Membership) *Membership {
return &Membership{
ID: membership.ID,
CreatedAt: membership.CreatedAt,
Identity: &Identity{
ID: membership.IdentityID,
},
Organization: &Organization{
ID: membership.OrganizationID,
},
Role: membership.Role,
Source: membership.Source,
State: membership.State,
Role: membership.Role,
Source: membership.Source,
State: membership.State,
}
}

View File

@@ -14,10 +14,56 @@
package types
import "go.probo.inc/probo/pkg/coredata"
import (
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/gid"
"go.probo.inc/probo/pkg/page"
)
func NewMembershipProfile(profile *coredata.MembershipProfile) *MembershipProfile {
return &MembershipProfile{
type (
ProfileOrderBy OrderBy[coredata.MembershipProfileOrderField]
ProfileConnection struct {
TotalCount int
Edges []*ProfileEdge
PageInfo PageInfo
Resolver any
ParentID gid.GID
}
)
func NewProfileConnection(
p *page.Page[*coredata.MembershipProfile, coredata.MembershipProfileOrderField],
resolver any,
parentID gid.GID,
) *ProfileConnection {
edges := make([]*ProfileEdge, len(p.Data))
for i, profile := range p.Data {
edges[i] = NewProfileEdge(profile, p.Cursor.OrderBy.Field)
}
return &ProfileConnection{
Edges: edges,
PageInfo: *NewPageInfo(p),
Resolver: resolver,
ParentID: parentID,
}
}
func NewProfileEdge(
profile *coredata.MembershipProfile,
orderField coredata.MembershipProfileOrderField,
) *ProfileEdge {
return &ProfileEdge{
Node: NewProfile(profile),
Cursor: profile.CursorKey(orderField),
}
}
func NewProfile(profile *coredata.MembershipProfile) *Profile {
return &Profile{
ID: profile.ID,
FullName: profile.FullName,
AdditionalEmailAddresses: profile.AdditionalEmailAddresses,

View File

@@ -72,11 +72,12 @@ func NewSCIMEvent(scimEvent *coredata.SCIMEvent) *SCIMEvent {
CreatedAt: scimEvent.CreatedAt,
}
if scimEvent.MembershipID != nil {
event.Membership = &Membership{
ID: *scimEvent.MembershipID,
}
}
// FIXME: profile
// if scimEvent.MembershipID != nil {
// event.Membership = &Membership{
// ID: *scimEvent.MembershipID,
// }
// }
return event
}

View File

@@ -30,8 +30,8 @@ type AcceptInvitationInput struct {
}
type AcceptInvitationPayload struct {
MembershipEdge *MembershipEdge `json:"membershipEdge"`
Invitation *Invitation `json:"invitation"`
Membership *Membership `json:"membership"`
Invitation *Invitation `json:"invitation"`
}
type AssumeOrganizationSessionInput struct {
@@ -79,8 +79,8 @@ type CreateOrganizationInput struct {
}
type CreateOrganizationPayload struct {
Organization *Organization `json:"organization,omitempty"`
MembershipEdge *MembershipEdge `json:"membershipEdge"`
Organization *Organization `json:"organization,omitempty"`
Membership *Membership `json:"membership"`
}
type CreatePersonalAPIKeyInput struct {
@@ -176,7 +176,7 @@ type Identity struct {
EmailVerified bool `json:"emailVerified"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Memberships *MembershipConnection `json:"memberships,omitempty"`
Profiles *ProfileConnection `json:"profiles,omitempty"`
PendingInvitations *InvitationConnection `json:"pendingInvitations,omitempty"`
Sessions *SessionConnection `json:"sessions,omitempty"`
PersonalAPIKeys *PersonalAPIKeyConnection `json:"personalAPIKeys,omitempty"`
@@ -220,45 +220,18 @@ type InviteMemberPayload struct {
}
type Membership struct {
ID gid.GID `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Identity *Identity `json:"identity,omitempty"`
Profile *MembershipProfile `json:"profile,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Role coredata.MembershipRole `json:"role"`
Source coredata.MembershipSource `json:"source"`
State coredata.MembershipState `json:"state"`
LastSession *Session `json:"lastSession,omitempty"`
Permission bool `json:"permission"`
ID gid.GID `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Role coredata.MembershipRole `json:"role"`
Source coredata.MembershipSource `json:"source"`
State coredata.MembershipState `json:"state"`
LastSession *Session `json:"lastSession,omitempty"`
Permission bool `json:"permission"`
}
func (Membership) IsNode() {}
func (this Membership) GetID() gid.GID { return this.ID }
type MembershipEdge struct {
Node *Membership `json:"node"`
Cursor page.CursorKey `json:"cursor"`
}
type MembershipProfile struct {
ID gid.GID `json:"id"`
FullName string `json:"fullName"`
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses"`
Kind coredata.MembershipProfileKind `json:"kind"`
Position *string `json:"position,omitempty"`
ContractStartDate *time.Time `json:"contractStartDate,omitempty"`
ContractEndDate *time.Time `json:"contractEndDate,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Identity *Identity `json:"identity,omitempty"`
Organization *Organization `json:"organization,omitempty"`
MembershipID gid.GID `json:"membershipId"`
Permission bool `json:"permission"`
}
func (MembershipProfile) IsNode() {}
func (this MembershipProfile) GetID() gid.GID { return this.ID }
type Mutation struct {
}
@@ -273,11 +246,11 @@ type Organization struct {
HeadquarterAddress *string `json:"headquarterAddress,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Members *MembershipConnection `json:"members,omitempty"`
Profiles *ProfileConnection `json:"profiles,omitempty"`
Invitations *InvitationConnection `json:"invitations,omitempty"`
SamlConfigurations *SAMLConfigurationConnection `json:"samlConfigurations,omitempty"`
ScimConfiguration *SCIMConfiguration `json:"scimConfiguration,omitempty"`
ViewerMembership *Membership `json:"viewerMembership,omitempty"`
Viewer *Profile `json:"viewer,omitempty"`
Permission bool `json:"permission"`
}
@@ -322,6 +295,30 @@ type PersonalAPIKeyEdge struct {
Cursor page.CursorKey `json:"cursor"`
}
type Profile struct {
ID gid.GID `json:"id"`
FullName string `json:"fullName"`
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses"`
Kind coredata.MembershipProfileKind `json:"kind"`
Position *string `json:"position,omitempty"`
ContractStartDate *time.Time `json:"contractStartDate,omitempty"`
ContractEndDate *time.Time `json:"contractEndDate,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Identity *Identity `json:"identity,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Membership *Membership `json:"membership,omitempty"`
Permission bool `json:"permission"`
}
func (Profile) IsNode() {}
func (this Profile) GetID() gid.GID { return this.ID }
type ProfileEdge struct {
Cursor page.CursorKey `json:"cursor"`
Node *Profile `json:"node"`
}
type Query struct {
}
@@ -448,17 +445,17 @@ func (SCIMConfiguration) IsNode() {}
func (this SCIMConfiguration) GetID() gid.GID { return this.ID }
type SCIMEvent struct {
ID gid.GID `json:"id"`
Method string `json:"method"`
Path string `json:"path"`
StatusCode int `json:"statusCode"`
RequestBody *string `json:"requestBody,omitempty"`
ResponseBody *string `json:"responseBody,omitempty"`
ErrorMessage *string `json:"errorMessage,omitempty"`
Membership *Membership `json:"membership,omitempty"`
IPAddress string `json:"ipAddress"`
CreatedAt time.Time `json:"createdAt"`
Permission bool `json:"permission"`
ID gid.GID `json:"id"`
Method string `json:"method"`
Path string `json:"path"`
StatusCode int `json:"statusCode"`
RequestBody *string `json:"requestBody,omitempty"`
ResponseBody *string `json:"responseBody,omitempty"`
ErrorMessage *string `json:"errorMessage,omitempty"`
Profile *Profile `json:"profile,omitempty"`
IPAddress string `json:"ipAddress"`
CreatedAt time.Time `json:"createdAt"`
Permission bool `json:"permission"`
}
func (SCIMEvent) IsNode() {}
@@ -564,7 +561,7 @@ type UpdateProfileInput struct {
}
type UpdateProfilePayload struct {
Profile *MembershipProfile `json:"profile"`
Profile *Profile `json:"profile"`
}
type UpdateSAMLConfigurationInput struct {

View File

@@ -23,6 +23,7 @@ import (
"go.probo.inc/probo/pkg/server/api/authz"
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
types1 "go.probo.inc/probo/pkg/server/api/console/v1/types"
"go.probo.inc/probo/pkg/server/gqlutils"
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
)
@@ -32,39 +33,9 @@ func (r *connectorResolver) Permission(ctx context.Context, obj *types.Connector
return r.Resolver.Permission(ctx, obj, action)
}
// Memberships is the resolver for the memberships field.
func (r *identityResolver) Memberships(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil {
return nil, err
}
if gqlutils.OnlyTotalCountSelected(ctx) {
return &types.MembershipConnection{
Resolver: r,
ParentID: obj.ID,
}, nil
}
pageOrderBy := page.OrderBy[coredata.MembershipOrderField]{
Field: coredata.MembershipOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.MembershipOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
page, err := r.iam.AccountService.ListMemberships(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewMembershipConnection(page, r, obj.ID), nil
// Profiles is the resolver for the profiles field.
func (r *identityResolver) Profiles(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types1.ProfileOrderBy) (*types1.ProfileConnection, error) {
panic(fmt.Errorf("not implemented: Profiles - profiles"))
}
// PendingInvitations is the resolver for the pendingInvitations field.
@@ -267,73 +238,6 @@ func (r *invitationConnectionResolver) TotalCount(ctx context.Context, obj *type
return nil, gqlutils.Internal(ctx)
}
// Identity is the resolver for the identity field.
func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership) (*types.Identity, error) {
if err := r.authorize(
ctx,
obj.Identity.ID,
iam.ActionIdentityGet,
authz.WithAttr("organization_id", obj.Organization.ID.String()),
); err != nil {
return nil, err
}
if gqlutils.OnlyIDSelected(ctx) {
return &types.Identity{
ID: obj.Identity.ID,
}, nil
}
identity, err := r.iam.AccountService.GetIdentityForMembership(ctx, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get identity for membership", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewIdentity(identity), nil
}
// Profile is the resolver for the profile field.
func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) (*types.MembershipProfile, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet, authz.WithSkipAssumptionCheck()); err != nil {
return nil, err
}
profile, err := r.iam.AccountService.GetProfileForMembership(ctx, obj.ID)
if err != nil {
var errProfileNotFound *iam.ErrProfileNotFound
if errors.As(err, &errProfileNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot get profile for membership", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewMembershipProfile(profile), nil
}
// Organization is the resolver for the organization field.
func (r *membershipResolver) Organization(ctx context.Context, obj *types.Membership) (*types.Organization, error) {
if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
return nil, err
}
if gqlutils.OnlyIDSelected(ctx) {
return &types.Organization{
ID: obj.Organization.ID,
}, nil
}
organization, err := r.iam.OrganizationService.GetOrganizationForMembership(ctx, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get organization for membership", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewOrganization(organization), nil
}
// LastSession is the resolver for the lastSession field.
func (r *membershipResolver) LastSession(ctx context.Context, obj *types.Membership) (*types.Session, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipGet, authz.WithSkipAssumptionCheck()); err != nil {
@@ -364,87 +268,6 @@ func (r *membershipResolver) Permission(ctx context.Context, obj *types.Membersh
return r.Resolver.Permission(ctx, obj, action)
}
// TotalCount is the resolver for the totalCount field.
func (r *membershipConnectionResolver) TotalCount(ctx context.Context, obj *types.MembershipConnection) (*int, error) {
if err := r.authorize(ctx, obj.ParentID, iam.ActionMembershipList); err != nil {
return nil, err
}
switch obj.Resolver.(type) {
case *identityResolver:
count, err := r.iam.AccountService.CountMemberships(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count memberships", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &count, nil
case *organizationResolver:
count, err := r.iam.OrganizationService.CountMemberships(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count memberships", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &count, nil
}
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
return nil, gqlutils.Internal(ctx)
}
// Identity is the resolver for the identity field.
func (r *membershipProfileResolver) Identity(ctx context.Context, obj *types.MembershipProfile) (*types.Identity, error) {
if err := r.authorize(
ctx,
obj.Identity.ID,
iam.ActionIdentityGet,
authz.WithAttr("organization_id", obj.Organization.ID.String()),
); err != nil {
return nil, err
}
if gqlutils.OnlyIDSelected(ctx) {
return &types.Identity{
ID: obj.Identity.ID,
}, nil
}
identity, err := r.iam.AccountService.GetIdentity(ctx, obj.Identity.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get identity for membership", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewIdentity(identity), nil
}
// Organization is the resolver for the organization field.
func (r *membershipProfileResolver) Organization(ctx context.Context, obj *types.MembershipProfile) (*types.Organization, error) {
if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
return nil, err
}
if gqlutils.OnlyIDSelected(ctx) {
return &types.Organization{
ID: obj.Organization.ID,
}, nil
}
organization, err := r.iam.OrganizationService.GetOrganizationForMembership(ctx, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get organization for membership", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewOrganization(organization), nil
}
// Permission is the resolver for the permission field.
func (r *membershipProfileResolver) Permission(ctx context.Context, obj *types.MembershipProfile, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// SignIn is the resolver for the signIn field.
func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput) (*types.SignInPayload, error) {
identity, err := r.iam.AuthService.CheckCredentials(ctx, input.Email, input.Password)
@@ -938,8 +761,8 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
}
return &types.CreateOrganizationPayload{
Organization: types.NewOrganization(organization),
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
Organization: types.NewOrganization(organization),
Membership: types.NewMembership(membership),
}, nil
}
@@ -1105,7 +928,7 @@ func (r *mutationResolver) UpdateProfile(ctx context.Context, input types.Update
}
return &types.UpdateProfilePayload{
Profile: types.NewMembershipProfile(profile),
Profile: types.NewProfile(profile),
}, nil
}
@@ -1173,8 +996,8 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc
}
return &types.AcceptInvitationPayload{
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
Invitation: types.NewInvitation(invitation),
Membership: types.NewMembership(membership),
Invitation: types.NewInvitation(invitation),
}, nil
}
@@ -1387,37 +1210,9 @@ func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types
return presignedURL, nil
}
// Members is the resolver for the members field.
func (r *organizationResolver) Members(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil {
return nil, err
}
if gqlutils.OnlyTotalCountSelected(ctx) {
return &types.MembershipConnection{
Resolver: r,
ParentID: obj.ID,
}, nil
}
pageOrderBy := page.OrderBy[coredata.MembershipOrderField]{
Field: coredata.MembershipOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy.Field = coredata.MembershipOrderField(orderBy.Field)
pageOrderBy.Direction = page.OrderDirection(orderBy.Direction)
}
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
page, err := r.iam.OrganizationService.ListMembers(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewMembershipConnection(page, r, obj.ID), nil
// Profiles is the resolver for the profiles field.
func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types1.ProfileOrderBy) (*types1.ProfileConnection, error) {
panic(fmt.Errorf("not implemented: Profiles - profiles"))
}
// Invitations is the resolver for the invitations field.
@@ -1575,6 +1370,41 @@ func (r *personalAPIKeyConnectionResolver) TotalCount(ctx context.Context, obj *
return nil, gqlutils.Internal(ctx)
}
// Identity is the resolver for the identity field.
func (r *profileResolver) Identity(ctx context.Context, obj *types.Profile) (*types.Identity, error) {
panic(fmt.Errorf("not implemented: Identity - identity"))
}
// Organization is the resolver for the organization field.
func (r *profileResolver) Organization(ctx context.Context, obj *types.Profile) (*types.Organization, error) {
panic(fmt.Errorf("not implemented: Organization - organization"))
}
// Membership is the resolver for the membership field.
func (r *profileResolver) Membership(ctx context.Context, obj *types.Profile) (*types.Membership, error) {
panic(fmt.Errorf("not implemented: Membership - membership"))
}
// Permission is the resolver for the permission field.
func (r *profileResolver) Permission(ctx context.Context, obj *types.Profile, action string) (bool, error) {
panic(fmt.Errorf("not implemented: Permission - permission"))
}
// TotalCount is the resolver for the totalCount field.
func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types1.ProfileConnection) (int, error) {
panic(fmt.Errorf("not implemented: TotalCount - totalCount"))
}
// Edges is the resolver for the edges field.
func (r *profileConnectionResolver) Edges(ctx context.Context, obj *types1.ProfileConnection) ([]*types.ProfileEdge, error) {
panic(fmt.Errorf("not implemented: Edges - edges"))
}
// PageInfo is the resolver for the pageInfo field.
func (r *profileConnectionResolver) PageInfo(ctx context.Context, obj *types1.ProfileConnection) (*types.PageInfo, error) {
panic(fmt.Errorf("not implemented: PageInfo - pageInfo"))
}
// Node is the resolver for the node field.
func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) {
var (
@@ -1620,7 +1450,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
return nil, err
}
return types.NewMembershipProfile(profile), nil
return types.NewProfile(profile), nil
}
case coredata.MembershipEntityType:
action = iam.ActionMembershipGet
@@ -2042,16 +1872,6 @@ func (r *Resolver) InvitationConnection() schema.InvitationConnectionResolver {
// Membership returns schema.MembershipResolver implementation.
func (r *Resolver) Membership() schema.MembershipResolver { return &membershipResolver{r} }
// MembershipConnection returns schema.MembershipConnectionResolver implementation.
func (r *Resolver) MembershipConnection() schema.MembershipConnectionResolver {
return &membershipConnectionResolver{r}
}
// MembershipProfile returns schema.MembershipProfileResolver implementation.
func (r *Resolver) MembershipProfile() schema.MembershipProfileResolver {
return &membershipProfileResolver{r}
}
// Mutation returns schema.MutationResolver implementation.
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
@@ -2066,6 +1886,14 @@ func (r *Resolver) PersonalAPIKeyConnection() schema.PersonalAPIKeyConnectionRes
return &personalAPIKeyConnectionResolver{r}
}
// Profile returns schema.ProfileResolver implementation.
func (r *Resolver) Profile() schema.ProfileResolver { return &profileResolver{r} }
// ProfileConnection returns schema.ProfileConnectionResolver implementation.
func (r *Resolver) ProfileConnection() schema.ProfileConnectionResolver {
return &profileConnectionResolver{r}
}
// Query returns schema.QueryResolver implementation.
func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} }
@@ -2108,12 +1936,12 @@ type identityResolver struct{ *Resolver }
type invitationResolver struct{ *Resolver }
type invitationConnectionResolver struct{ *Resolver }
type membershipResolver struct{ *Resolver }
type membershipConnectionResolver struct{ *Resolver }
type membershipProfileResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }
type organizationResolver struct{ *Resolver }
type personalAPIKeyResolver struct{ *Resolver }
type personalAPIKeyConnectionResolver struct{ *Resolver }
type profileResolver struct{ *Resolver }
type profileConnectionResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type sAMLConfigurationResolver struct{ *Resolver }
type sAMLConfigurationConnectionResolver struct{ *Resolver }