Update GraphQL, MCP, and CLI for the portal

Rewire the console and visitor resolvers onto the management and visitor
services with compliance-portal authorization. Rename the GraphQL and MCP
ComplianceExternalURL type to ComplianceCustomLink, expose trust center
profile fields, default and custom domains, public URL, and the managed
flag, and drop the profile fields from the organization surface.

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-07-10 15:15:09 +02:00
parent 860dafeaf2
commit ce1b64b529
43 changed files with 921 additions and 1459 deletions

View File

@@ -14,6 +14,7 @@ import (
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/accessreview"
"go.probo.inc/probo/pkg/agentrun"
"go.probo.inc/probo/pkg/complianceportal"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/gid"
"go.probo.inc/probo/pkg/probo"
@@ -334,9 +335,9 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
return types.NewTransferImpactAssessment(tia), nil
}
case coredata.TrustCenterEntityType:
action = probo.ActionTrustCenterGet
action = complianceportal.ActionCompliancePortalGet
loadNode = func(ctx context.Context, scope *coredata.Scope, id gid.GID) (types.Node, error) {
trustCenter, err := r.probo.TrustCenters.Get(ctx, scope, id)
trustCenter, err := r.management.Get(ctx, scope, id)
if err != nil {
return nil, err
}
@@ -344,9 +345,9 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
return types.NewTrustCenter(trustCenter), nil
}
case coredata.TrustCenterAccessEntityType:
action = probo.ActionTrustCenterAccessGet
action = complianceportal.ActionCompliancePortalAccessGet
loadNode = func(ctx context.Context, scope *coredata.Scope, id gid.GID) (types.Node, error) {
trustCenterAccess, err := r.probo.TrustCenterAccesses.Get(ctx, scope, id)
trustCenterAccess, err := r.management.GetAccess(ctx, scope, id)
if err != nil {
return nil, err
}

View File

@@ -93,10 +93,6 @@ type Organization implements Node {
logo: File @goField(forceResolver: true)
horizontalLogo: File @goField(forceResolver: true)
description: String
websiteUrl: String
email: String
headquarterAddress: String
context: OrganizationContext @goField(forceResolver: true)
profiles(
@@ -319,7 +315,6 @@ type Organization implements Node {
): AgentRunConnection! @goField(forceResolver: true)
trustCenter: TrustCenter @goField(forceResolver: true)
customDomain: CustomDomain @goField(forceResolver: true)
trustCenterFiles(
first: Int
after: CursorKey

View File

@@ -106,99 +106,17 @@ enum TrustCenterReferenceOrderField
)
}
enum CompliancePortalCommitmentGroupOrderField
enum ComplianceCustomLinkOrderField
@goModel(
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderField"
) {
RANK
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldRank"
)
CREATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldCreatedAt"
)
UPDATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldUpdatedAt"
)
}
enum CompliancePortalCommitmentOrderField
@goModel(
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderField"
) {
RANK
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldRank"
)
CREATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldCreatedAt"
)
UPDATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldUpdatedAt"
)
}
enum CompliancePortalCommitmentIcon
@goModel(
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIcon"
) {
LOCK_KEY
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLockKey")
EYE_SLASH
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEyeSlash")
FINGERPRINT
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconFingerprint")
SHIELD_WARNING
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldWarning")
SHIELD_CHECK
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldCheck")
SIREN
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconSiren")
KEY
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconKey")
LOCK
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLock")
CLOUD
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCloud")
DATABASE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconDatabase")
GLOBE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGlobe")
EYE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEye")
USERS
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconUsers")
CERTIFICATE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCertificate")
GAVEL
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGavel")
HEARTBEAT
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconHeartbeat")
BELL
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBell")
BUG
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBug")
CODE
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCode")
SERVER
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconServer")
}
enum ComplianceExternalURLOrderField
@goModel(
model: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField"
model: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderField"
) {
CREATED_AT
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldCreatedAt"
value: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderFieldCreatedAt"
)
RANK
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldRank"
value: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderFieldRank"
)
}
@@ -300,22 +218,6 @@ input TrustCenterReferenceOrder
field: TrustCenterReferenceOrderField!
}
input CompliancePortalCommitmentGroupOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupOrderBy"
) {
direction: OrderDirection!
field: CompliancePortalCommitmentGroupOrderField!
}
input CompliancePortalCommitmentOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentOrderBy"
) {
direction: OrderDirection!
field: CompliancePortalCommitmentOrderField!
}
input TrustCenterFileOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrustCenterFileOrderBy"
@@ -324,12 +226,12 @@ input TrustCenterFileOrder
field: TrustCenterFileOrderField!
}
input ComplianceExternalURLOrder
input ComplianceCustomLinkOrder
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLOrderBy"
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceCustomLinkOrderBy"
) {
direction: OrderDirection!
field: ComplianceExternalURLOrderField!
field: ComplianceCustomLinkOrderField!
}
input ComplianceFrameworkOrder
@@ -350,6 +252,10 @@ type TrustCenter implements Node
logo: File @goField(forceResolver: true)
darkLogo: File @goField(forceResolver: true)
nda: File @goField(forceResolver: true)
description: String
websiteUrl: String
email: String
headquarterAddress: String
createdAt: Datetime!
updatedAt: Datetime!
organization: Organization! @goField(forceResolver: true)
@@ -370,14 +276,6 @@ type TrustCenter implements Node
orderBy: TrustCenterReferenceOrder
): TrustCenterReferenceConnection! @goField(forceResolver: true)
commitmentGroups(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: CompliancePortalCommitmentGroupOrder
): CompliancePortalCommitmentGroupConnection! @goField(forceResolver: true)
complianceFrameworks(
first: Int
after: CursorKey
@@ -386,16 +284,22 @@ type TrustCenter implements Node
orderBy: ComplianceFrameworkOrder
): ComplianceFrameworkConnection! @goField(forceResolver: true)
externalUrls(
customLinks(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: ComplianceExternalURLOrder
): ComplianceExternalURLConnection! @goField(forceResolver: true)
orderBy: ComplianceCustomLinkOrder
): ComplianceCustomLinkConnection! @goField(forceResolver: true)
mailingList: MailingList @goField(forceResolver: true)
defaultDomain: CustomDomain @goField(forceResolver: true)
customDomain: CustomDomain @goField(forceResolver: true)
publicUrl: String! @goField(forceResolver: true)
permission(action: String!): Boolean! @goField(forceResolver: true)
}
@@ -495,66 +399,6 @@ type TrustCenterReferenceEdge {
node: TrustCenterReference!
}
type CompliancePortalCommitmentGroup implements Node {
id: ID!
title: String!
description: String!
rank: Int!
createdAt: Datetime!
updatedAt: Datetime!
commitments(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: CompliancePortalCommitmentOrder
): CompliancePortalCommitmentConnection! @goField(forceResolver: true)
permission(action: String!): Boolean! @goField(forceResolver: true)
}
type CompliancePortalCommitmentGroupConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupConnection"
) {
totalCount: Int! @goField(forceResolver: true)
edges: [CompliancePortalCommitmentGroupEdge!]!
pageInfo: PageInfo!
}
type CompliancePortalCommitmentGroupEdge {
cursor: CursorKey!
node: CompliancePortalCommitmentGroup!
}
type CompliancePortalCommitment implements Node {
id: ID!
icon: CompliancePortalCommitmentIcon!
eyebrow: String!
title: String!
description: String!
rank: Int!
createdAt: Datetime!
updatedAt: Datetime!
permission(action: String!): Boolean! @goField(forceResolver: true)
}
type CompliancePortalCommitmentConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentConnection"
) {
totalCount: Int! @goField(forceResolver: true)
edges: [CompliancePortalCommitmentEdge!]!
pageInfo: PageInfo!
}
type CompliancePortalCommitmentEdge {
cursor: CursorKey!
node: CompliancePortalCommitment!
}
type ComplianceFramework implements Node
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework"
@@ -580,7 +424,7 @@ type ComplianceFrameworkEdge {
node: ComplianceFramework!
}
type ComplianceExternalURL implements Node {
type ComplianceCustomLink implements Node {
id: ID!
name: String!
url: String!
@@ -591,17 +435,17 @@ type ComplianceExternalURL implements Node {
permission(action: String!): Boolean! @goField(forceResolver: true)
}
type ComplianceExternalURLConnection
type ComplianceCustomLinkConnection
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLConnection"
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceCustomLinkConnection"
) {
edges: [ComplianceExternalURLEdge!]!
edges: [ComplianceCustomLinkEdge!]!
pageInfo: PageInfo!
}
type ComplianceExternalURLEdge {
type ComplianceCustomLinkEdge {
cursor: CursorKey!
node: ComplianceExternalURL!
node: ComplianceCustomLink!
}
type TrustCenterFile implements Node {
@@ -636,6 +480,7 @@ type CustomDomain implements Node {
id: ID!
organization: Organization!
domain: String!
managed: Boolean!
sslStatus: SSLStatus!
sslExpiresAt: Datetime
provisioningError: String
@@ -680,24 +525,6 @@ extend type Mutation {
deleteTrustCenterReference(
input: DeleteTrustCenterReferenceInput!
): DeleteTrustCenterReferencePayload!
createCompliancePortalCommitmentGroup(
input: CreateCompliancePortalCommitmentGroupInput!
): CreateCompliancePortalCommitmentGroupPayload!
updateCompliancePortalCommitmentGroup(
input: UpdateCompliancePortalCommitmentGroupInput!
): UpdateCompliancePortalCommitmentGroupPayload!
deleteCompliancePortalCommitmentGroup(
input: DeleteCompliancePortalCommitmentGroupInput!
): DeleteCompliancePortalCommitmentGroupPayload!
createCompliancePortalCommitment(
input: CreateCompliancePortalCommitmentInput!
): CreateCompliancePortalCommitmentPayload!
updateCompliancePortalCommitment(
input: UpdateCompliancePortalCommitmentInput!
): UpdateCompliancePortalCommitmentPayload!
deleteCompliancePortalCommitment(
input: DeleteCompliancePortalCommitmentInput!
): DeleteCompliancePortalCommitmentPayload!
createComplianceFramework(
input: CreateComplianceFrameworkInput!
): CreateComplianceFrameworkPayload!
@@ -707,15 +534,15 @@ extend type Mutation {
deleteComplianceFramework(
input: DeleteComplianceFrameworkInput!
): DeleteComplianceFrameworkPayload!
createComplianceExternalURL(
input: CreateComplianceExternalURLInput!
): CreateComplianceExternalURLPayload!
updateComplianceExternalURL(
input: UpdateComplianceExternalURLInput!
): UpdateComplianceExternalURLPayload!
deleteComplianceExternalURL(
input: DeleteComplianceExternalURLInput!
): DeleteComplianceExternalURLPayload!
createComplianceCustomLink(
input: CreateComplianceCustomLinkInput!
): CreateComplianceCustomLinkPayload!
updateComplianceCustomLink(
input: UpdateComplianceCustomLinkInput!
): UpdateComplianceCustomLinkPayload!
deleteComplianceCustomLink(
input: DeleteComplianceCustomLinkInput!
): DeleteComplianceCustomLinkPayload!
createTrustCenterFile(
input: CreateTrustCenterFileInput!
): CreateTrustCenterFilePayload!
@@ -740,6 +567,10 @@ input UpdateTrustCenterInput {
trustCenterId: ID!
active: Boolean
searchEngineIndexing: SearchEngineIndexing
description: String @goField(omittable: true)
websiteUrl: String @goField(omittable: true)
email: String @goField(omittable: true)
headquarterAddress: String @goField(omittable: true)
}
input UploadTrustCenterNDAInput {
@@ -797,44 +628,6 @@ input DeleteTrustCenterReferenceInput {
id: ID!
}
input CreateCompliancePortalCommitmentGroupInput {
trustCenterId: ID!
title: String!
description: String!
}
input UpdateCompliancePortalCommitmentGroupInput {
id: ID!
title: String
description: String
rank: Int
}
input DeleteCompliancePortalCommitmentGroupInput {
id: ID!
}
input CreateCompliancePortalCommitmentInput {
groupId: ID!
icon: CompliancePortalCommitmentIcon!
eyebrow: String!
title: String!
description: String!
}
input UpdateCompliancePortalCommitmentInput {
id: ID!
icon: CompliancePortalCommitmentIcon
eyebrow: String
title: String
description: String
rank: Int
}
input DeleteCompliancePortalCommitmentInput {
id: ID!
}
input CreateComplianceFrameworkInput {
trustCenterId: ID!
frameworkId: ID!
@@ -849,20 +642,20 @@ input DeleteComplianceFrameworkInput {
id: ID!
}
input CreateComplianceExternalURLInput {
input CreateComplianceCustomLinkInput {
trustCenterId: ID!
name: String!
url: String!
}
input UpdateComplianceExternalURLInput {
input UpdateComplianceCustomLinkInput {
id: ID!
name: String!
url: String!
rank: Int
}
input DeleteComplianceExternalURLInput {
input DeleteComplianceCustomLinkInput {
id: ID!
}
@@ -890,12 +683,12 @@ input DeleteTrustCenterFileInput {
}
input CreateCustomDomainInput {
organizationId: ID!
trustCenterId: ID!
domain: String!
}
input DeleteCustomDomainInput {
organizationId: ID!
customDomainId: ID!
}
type UpdateTrustCenterPayload {
@@ -934,30 +727,6 @@ type DeleteTrustCenterReferencePayload {
deletedTrustCenterReferenceId: ID!
}
type CreateCompliancePortalCommitmentGroupPayload {
compliancePortalCommitmentGroupEdge: CompliancePortalCommitmentGroupEdge!
}
type UpdateCompliancePortalCommitmentGroupPayload {
compliancePortalCommitmentGroup: CompliancePortalCommitmentGroup!
}
type DeleteCompliancePortalCommitmentGroupPayload {
deletedCompliancePortalCommitmentGroupId: ID!
}
type CreateCompliancePortalCommitmentPayload {
compliancePortalCommitmentEdge: CompliancePortalCommitmentEdge!
}
type UpdateCompliancePortalCommitmentPayload {
compliancePortalCommitment: CompliancePortalCommitment!
}
type DeleteCompliancePortalCommitmentPayload {
deletedCompliancePortalCommitmentId: ID!
}
type CreateComplianceFrameworkPayload {
complianceFrameworkEdge: ComplianceFrameworkEdge!
}
@@ -970,16 +739,16 @@ type DeleteComplianceFrameworkPayload {
deletedComplianceFrameworkId: ID!
}
type CreateComplianceExternalURLPayload {
complianceExternalUrlEdge: ComplianceExternalURLEdge!
type CreateComplianceCustomLinkPayload {
complianceCustomLinkEdge: ComplianceCustomLinkEdge!
}
type UpdateComplianceExternalURLPayload {
complianceExternalUrl: ComplianceExternalURL!
type UpdateComplianceCustomLinkPayload {
complianceCustomLink: ComplianceCustomLink!
}
type DeleteComplianceExternalURLPayload {
deletedComplianceExternalUrlId: ID!
type DeleteComplianceCustomLinkPayload {
deletedComplianceCustomLinkId: ID!
}
type CreateTrustCenterFilePayload {

View File

@@ -27,6 +27,7 @@ import (
"go.probo.inc/probo/pkg/accessreview"
"go.probo.inc/probo/pkg/agentrun"
"go.probo.inc/probo/pkg/baseurl"
"go.probo.inc/probo/pkg/complianceportal/management"
"go.probo.inc/probo/pkg/connector"
"go.probo.inc/probo/pkg/connector/provider"
"go.probo.inc/probo/pkg/cookiebanner"
@@ -49,6 +50,7 @@ func NewGraphQLHandler(
proboSvc *probo.Service,
resourceAliasSvc *resourcealias.Service,
esignSvc *esign.Service,
managementSvc *management.Service,
accessReviewSvc *accessreview.Service,
agentRunSvc *agentrun.Service,
mailmanSvc *mailman.Service,
@@ -72,6 +74,7 @@ func NewGraphQLHandler(
resourceAlias: resourceAliasSvc,
iam: iamSvc,
esign: esignSvc,
management: managementSvc,
accessReview: accessReviewSvc,
agentRun: agentRunSvc,
mailman: mailmanSvc,

View File

@@ -11,10 +11,10 @@ import (
"fmt"
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/complianceportal"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/mailman"
"go.probo.inc/probo/pkg/page"
"go.probo.inc/probo/pkg/probo"
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
"go.probo.inc/probo/pkg/server/api/console/v1/types"
"go.probo.inc/probo/pkg/server/gqlutils"
@@ -23,7 +23,7 @@ import (
// Subscribers is the resolver for the subscribers field on MailingList.
func (r *mailingListResolver) Subscribers(ctx context.Context, obj *types.MailingList, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.MailingListSubscriberConnection, error) {
if _, err := r.authorize(ctx, obj.ID, probo.ActionMailingListSubscriberList); err != nil {
if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionMailingListSubscriberList); err != nil {
return nil, err
}
@@ -45,7 +45,7 @@ func (r *mailingListResolver) Subscribers(ctx context.Context, obj *types.Mailin
// Updates is the resolver for the updates field on MailingList.
func (r *mailingListResolver) Updates(ctx context.Context, obj *types.MailingList, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.MailingListUpdateConnection, error) {
if _, err := r.authorize(ctx, obj.ID, probo.ActionMailingListUpdateList); err != nil {
if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionMailingListUpdateList); err != nil {
return nil, err
}
@@ -67,7 +67,7 @@ func (r *mailingListResolver) Updates(ctx context.Context, obj *types.MailingLis
// TotalCount is the resolver for the totalCount field.
func (r *mailingListSubscriberConnectionResolver) TotalCount(ctx context.Context, obj *types.MailingListSubscriberConnection) (int, error) {
if _, err := r.authorize(ctx, obj.ParentID, probo.ActionMailingListSubscriberList); err != nil {
if _, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionMailingListSubscriberList); err != nil {
return 0, err
}
@@ -89,7 +89,7 @@ func (r *mailingListSubscriberConnectionResolver) TotalCount(ctx context.Context
// TotalCount is the resolver for the totalCount field on MailingListUpdateConnection.
func (r *mailingListUpdateConnectionResolver) TotalCount(ctx context.Context, obj *types.MailingListUpdateConnection) (int, error) {
if _, err := r.authorize(ctx, obj.ParentID, probo.ActionMailingListUpdateList); err != nil {
if _, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionMailingListUpdateList); err != nil {
return 0, err
}
@@ -104,7 +104,7 @@ func (r *mailingListUpdateConnectionResolver) TotalCount(ctx context.Context, ob
// CreateMailingListUpdate is the resolver for the createMailingListUpdate field.
func (r *mutationResolver) CreateMailingListUpdate(ctx context.Context, input types.CreateMailingListUpdateInput) (*types.CreateMailingListUpdatePayload, error) {
if _, err := r.authorize(ctx, input.MailingListID, probo.ActionMailingListUpdateCreate); err != nil {
if _, err := r.authorize(ctx, input.MailingListID, complianceportal.ActionMailingListUpdateCreate); err != nil {
return nil, err
}
@@ -133,7 +133,7 @@ func (r *mutationResolver) CreateMailingListUpdate(ctx context.Context, input ty
// UpdateMailingListUpdate is the resolver for the updateMailingListUpdate field.
func (r *mutationResolver) UpdateMailingListUpdate(ctx context.Context, input types.UpdateMailingListUpdateInput) (*types.UpdateMailingListUpdatePayload, error) {
if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateUpdate); err != nil {
if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateUpdate); err != nil {
return nil, err
}
@@ -170,7 +170,7 @@ func (r *mutationResolver) UpdateMailingListUpdate(ctx context.Context, input ty
// SendMailingListUpdate is the resolver for the sendMailingListUpdate field.
func (r *mutationResolver) SendMailingListUpdate(ctx context.Context, input types.SendMailingListUpdateInput) (*types.SendMailingListUpdatePayload, error) {
if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateUpdate); err != nil {
if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateUpdate); err != nil {
return nil, err
}
@@ -196,7 +196,7 @@ func (r *mutationResolver) SendMailingListUpdate(ctx context.Context, input type
// DeleteMailingListUpdate is the resolver for the deleteMailingListUpdate field.
func (r *mutationResolver) DeleteMailingListUpdate(ctx context.Context, input types.DeleteMailingListUpdateInput) (*types.DeleteMailingListUpdatePayload, error) {
if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateDelete); err != nil {
if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateDelete); err != nil {
return nil, err
}
@@ -217,7 +217,7 @@ func (r *mutationResolver) DeleteMailingListUpdate(ctx context.Context, input ty
// UpdateMailingList is the resolver for the updateMailingList field.
func (r *mutationResolver) UpdateMailingList(ctx context.Context, input types.UpdateMailingListInput) (*types.UpdateMailingListPayload, error) {
if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdate); err != nil {
if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdate); err != nil {
return nil, err
}
@@ -234,7 +234,7 @@ func (r *mutationResolver) UpdateMailingList(ctx context.Context, input types.Up
// CreateMailingListSubscriber is the resolver for the createMailingListSubscriber field.
func (r *mutationResolver) CreateMailingListSubscriber(ctx context.Context, input types.CreateMailingListSubscriberInput) (*types.CreateMailingListSubscriberPayload, error) {
if _, err := r.authorize(ctx, input.MailingListID, probo.ActionMailingListSubscriberCreate); err != nil {
if _, err := r.authorize(ctx, input.MailingListID, complianceportal.ActionMailingListSubscriberCreate); err != nil {
return nil, err
}
@@ -268,7 +268,7 @@ func (r *mutationResolver) CreateMailingListSubscriber(ctx context.Context, inpu
// DeleteMailingListSubscriber is the resolver for the deleteMailingListSubscriber field.
func (r *mutationResolver) DeleteMailingListSubscriber(ctx context.Context, input types.DeleteMailingListSubscriberInput) (*types.DeleteMailingListSubscriberPayload, error) {
if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListSubscriberDelete); err != nil {
if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListSubscriberDelete); err != nil {
return nil, err
}

View File

@@ -13,6 +13,7 @@ import (
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/accessreview"
"go.probo.inc/probo/pkg/agentrun"
"go.probo.inc/probo/pkg/complianceportal"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/gid"
"go.probo.inc/probo/pkg/iam"
@@ -1158,12 +1159,12 @@ func (r *organizationResolver) AgentRuns(ctx context.Context, obj *types.Organiz
// TrustCenter is the resolver for the trustCenter field.
func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) {
scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet)
scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalGet)
if err != nil {
return nil, err
}
trustCenter, err := r.probo.TrustCenters.GetByOrganizationID(ctx, scope, obj.ID)
trustCenter, err := r.management.GetByOrganizationID(ctx, scope, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -1172,29 +1173,9 @@ func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organ
return types.NewTrustCenter(trustCenter), nil
}
// CustomDomain is the resolver for the customDomain field.
func (r *organizationResolver) CustomDomain(ctx context.Context, obj *types.Organization) (*types.CustomDomain, error) {
scope, err := r.authorize(ctx, obj.ID, probo.ActionCustomDomainGet)
if err != nil {
return nil, err
}
domain, err := r.probo.CustomDomains.GetOrganizationCustomDomain(ctx, scope, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
if domain == nil {
return nil, nil
}
return types.NewCustomDomain(domain, r.customDomainCname), nil
}
// TrustCenterFiles is the resolver for the trustCenterFiles field.
func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterFileOrderField]) (*types.TrustCenterFileConnection, error) {
scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileList)
scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalFileList)
if err != nil {
return nil, err
}
@@ -1213,7 +1194,7 @@ func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
pageResult, err := r.probo.TrustCenterFiles.ListForOrganizationID(ctx, scope, obj.ID, cursor, &coredata.TrustCenterFileFilter{})
pageResult, err := r.management.ListFilesForOrganizationID(ctx, scope, obj.ID, cursor, &coredata.TrustCenterFileFilter{})
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list organization trust center files", log.Error(err))
return nil, gqlutils.Internal(ctx)

View File

@@ -35,6 +35,7 @@ import (
"go.probo.inc/probo/pkg/accessreview"
"go.probo.inc/probo/pkg/agentrun"
"go.probo.inc/probo/pkg/baseurl"
"go.probo.inc/probo/pkg/complianceportal/management"
"go.probo.inc/probo/pkg/connector"
"go.probo.inc/probo/pkg/connector/provider"
"go.probo.inc/probo/pkg/cookiebanner"
@@ -65,6 +66,7 @@ type (
resourceAlias *resourcealias.Service
iam *iam.Service
esign *esign.Service
management *management.Service
accessReview *accessreview.Service
agentRun *agentrun.Service
mailman *mailman.Service
@@ -81,12 +83,29 @@ type (
}
)
// newCustomDomainType loads the domain's certificate (when present) and builds
// the GraphQL CustomDomain type with its certificate-backed SSL fields.
func (r *Resolver) newCustomDomainType(
ctx context.Context,
scope coredata.Scoper,
domain *coredata.CustomDomain,
) (*types.CustomDomain, error) {
cert, err := r.management.GetCertificate(ctx, scope, domain)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot load certificate", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewCustomDomain(domain, cert, r.customDomainCname), nil
}
func NewMux(
logger *log.Logger,
proboSvc *probo.Service,
resourceAliasSvc *resourcealias.Service,
iamSvc *iam.Service,
esignSvc *esign.Service,
managementSvc *management.Service,
accessReviewSvc *accessreview.Service,
agentRunSvc *agentrun.Service,
mailmanSvc *mailman.Service,
@@ -111,6 +130,7 @@ func NewMux(
proboSvc,
resourceAliasSvc,
esignSvc,
managementSvc,
accessReviewSvc,
agentRunSvc,
mailmanSvc,

File diff suppressed because it is too large Load Diff

View File

@@ -25,15 +25,15 @@ import (
"go.probo.inc/probo/pkg/page"
)
type ComplianceExternalURLOrderBy = OrderBy[coredata.ComplianceExternalURLOrderField]
type ComplianceCustomLinkOrderBy = OrderBy[coredata.ComplianceCustomLinkOrderField]
type ComplianceExternalURLConnection struct {
Edges []*ComplianceExternalURLEdge `json:"edges"`
PageInfo *PageInfo `json:"pageInfo"`
type ComplianceCustomLinkConnection struct {
Edges []*ComplianceCustomLinkEdge `json:"edges"`
PageInfo *PageInfo `json:"pageInfo"`
}
func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL {
return &ComplianceExternalURL{
func NewComplianceCustomLink(c *coredata.ComplianceCustomLink) *ComplianceCustomLink {
return &ComplianceCustomLink{
ID: c.ID,
Name: c.Name,
URL: c.URL,
@@ -43,23 +43,23 @@ func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExte
}
}
func NewComplianceExternalURLConnection(
p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField],
) *ComplianceExternalURLConnection {
edges := make([]*ComplianceExternalURLEdge, len(p.Data))
func NewComplianceCustomLinkConnection(
p *page.Page[*coredata.ComplianceCustomLink, coredata.ComplianceCustomLinkOrderField],
) *ComplianceCustomLinkConnection {
edges := make([]*ComplianceCustomLinkEdge, len(p.Data))
for i := range edges {
edges[i] = NewComplianceExternalURLEdge(p.Data[i], p.Cursor.OrderBy.Field)
edges[i] = NewComplianceCustomLinkEdge(p.Data[i], p.Cursor.OrderBy.Field)
}
return &ComplianceExternalURLConnection{
return &ComplianceCustomLinkConnection{
Edges: edges,
PageInfo: NewPageInfo(p),
}
}
func NewComplianceExternalURLEdge(c *coredata.ComplianceExternalURL, orderBy coredata.ComplianceExternalURLOrderField) *ComplianceExternalURLEdge {
return &ComplianceExternalURLEdge{
func NewComplianceCustomLinkEdge(c *coredata.ComplianceCustomLink, orderBy coredata.ComplianceCustomLinkOrderField) *ComplianceCustomLinkEdge {
return &ComplianceCustomLinkEdge{
Cursor: c.CursorKey(orderBy),
Node: NewComplianceExternalURL(c),
Node: NewComplianceCustomLink(c),
}
}

View File

@@ -24,18 +24,26 @@ import (
"go.probo.inc/probo/pkg/coredata"
)
func NewCustomDomain(d *coredata.CustomDomain, cnameTarget string) *CustomDomain {
// NewCustomDomain builds the GraphQL CustomDomain type. The TLS lifecycle now
// lives on the linked certificate; when cert is nil (certificate not yet
// created) the domain reports a pending SSL status.
func NewCustomDomain(d *coredata.CustomDomain, cert *coredata.Certificate, cnameTarget string) *CustomDomain {
result := &CustomDomain{
ID: d.ID,
Organization: &Organization{
ID: d.OrganizationID,
},
Domain: d.Domain,
SslStatus: d.SSLStatus,
CreatedAt: d.CreatedAt,
UpdatedAt: d.UpdatedAt,
SslExpiresAt: d.SSLExpiresAt,
ProvisioningError: d.ProvisioningError,
Domain: d.Domain,
Managed: d.Managed,
SslStatus: coredata.CustomDomainSSLStatusPending,
CreatedAt: d.CreatedAt,
UpdatedAt: d.UpdatedAt,
}
if cert != nil {
result.SslStatus = coredata.CustomDomainSSLStatus(cert.Status)
result.SslExpiresAt = cert.SSLExpiresAt
result.ProvisioningError = cert.ProvisioningError
}
// Convert DNS records

View File

@@ -26,18 +26,14 @@ import (
func NewOrganization(o *coredata.Organization) *Organization {
org := &Organization{
ID: o.ID,
Name: o.Name,
Description: o.Description,
WebsiteURL: o.WebsiteURL,
Email: o.Email,
ID: o.ID,
Name: o.Name,
Context: &OrganizationContext{
OrganizationID: o.ID,
},
HeadquarterAddress: o.HeadquarterAddress,
CreatedAt: o.CreatedAt,
UpdatedAt: o.UpdatedAt,
CreatedAt: o.CreatedAt,
UpdatedAt: o.UpdatedAt,
}
if o.LogoFileID != nil {
@@ -48,11 +44,5 @@ func NewOrganization(o *coredata.Organization) *Organization {
org.HorizontalLogo = &File{ID: *o.HorizontalLogoFileID}
}
if o.CustomDomainID != nil {
org.CustomDomain = &CustomDomain{
ID: *o.CustomDomainID,
}
}
return org
}

View File

@@ -28,21 +28,25 @@ import (
)
type TrustCenter struct {
ID gid.GID `json:"id"`
Active bool `json:"active"`
SearchEngineIndexing coredata.SearchEngineIndexing `json:"searchEngineIndexing"`
Logo *File `json:"logo,omitempty"`
DarkLogo *File `json:"darkLogo,omitempty"`
Nda *File `json:"nda,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Organization *Organization `json:"organization"`
Accesses *TrustCenterAccessConnection `json:"accesses"`
References *TrustCenterReferenceConnection `json:"references"`
ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"`
ExternalUrls *ComplianceExternalURLConnection `json:"externalUrls"`
MailingList *MailingList `json:"mailingList,omitempty"`
Permission bool `json:"permission"`
ID gid.GID `json:"id"`
Active bool `json:"active"`
SearchEngineIndexing coredata.SearchEngineIndexing `json:"searchEngineIndexing"`
Logo *File `json:"logo,omitempty"`
DarkLogo *File `json:"darkLogo,omitempty"`
Nda *File `json:"nda,omitempty"`
Description *string `json:"description,omitempty"`
WebsiteURL *string `json:"websiteUrl,omitempty"`
Email *string `json:"email,omitempty"`
HeadquarterAddress *string `json:"headquarterAddress,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Organization *Organization `json:"organization"`
Accesses *TrustCenterAccessConnection `json:"accesses"`
References *TrustCenterReferenceConnection `json:"references"`
ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"`
CustomLinks *ComplianceCustomLinkConnection `json:"customLinks"`
MailingList *MailingList `json:"mailingList,omitempty"`
Permission bool `json:"permission"`
}
func (TrustCenter) IsNode() {}
@@ -56,6 +60,10 @@ func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
},
Active: tc.Active,
SearchEngineIndexing: tc.SearchEngineIndexing,
Description: tc.Description,
WebsiteURL: tc.WebsiteURL,
Email: tc.Email,
HeadquarterAddress: tc.HeadquarterAddress,
CreatedAt: tc.CreatedAt,
UpdatedAt: tc.UpdatedAt,
}