v1 hotfixes (#1320)

* fix: when grpcInsecure is set to true with no internal client overrides, use TLS strategy=none

* fix: invites
This commit is contained in:
abelanger5
2025-03-11 16:18:07 -04:00
committed by GitHub
parent 1f2096313d
commit afd853e223
9 changed files with 92 additions and 27 deletions

View File

@@ -20,7 +20,7 @@ func (t *UserService) UserListTenantInvites(ctx echo.Context, request gen.UserLi
rows := make([]gen.TenantInvite, len(invites))
for i := range invites {
rows[i] = *transformers.ToTenantInviteLink(invites[i])
rows[i] = *transformers.ToUserTenantInviteLink(invites[i])
}
return gen.UserListTenantInvites200JSONResponse(gen.TenantInviteList200JSONResponse{

View File

@@ -17,3 +17,16 @@ func ToTenantInviteLink(invite *dbsqlc.TenantInviteLink) *gen.TenantInvite {
return res
}
func ToUserTenantInviteLink(invite *dbsqlc.ListTenantInvitesByEmailRow) *gen.TenantInvite {
res := &gen.TenantInvite{
Metadata: *toAPIMetadata(sqlchelpers.UUIDToStr(invite.ID), invite.CreatedAt.Time, invite.UpdatedAt.Time),
Email: invite.InviteeEmail,
Expires: invite.Expires.Time,
Role: gen.TenantMemberRole(invite.Role),
TenantId: sqlchelpers.UUIDToStr(invite.TenantId),
TenantName: &invite.TenantName,
}
return res
}

View File

@@ -136,6 +136,10 @@ export function useTenant(): TenantContext {
return;
}
if (pathname.startsWith('/onboarding')) {
return;
}
setLastRedirected(tenant?.slug);
if (tenant?.version == TenantVersion.V0 && pathname.startsWith('/v1')) {
@@ -151,8 +155,6 @@ export function useTenant(): TenantContext {
search: params.toString(),
});
}
console.log(tenant?.version);
}, [lastRedirected, navigate, params, pathname, tenant]);
if (!tenant) {

View File

@@ -1,4 +1,4 @@
import api from '@/lib/api';
import api, { TenantVersion } from '@/lib/api';
import { useApiError } from '@/lib/hooks';
import { useMutation } from '@tanstack/react-query';
import {
@@ -32,12 +32,35 @@ export default function TenantInvites() {
const acceptMutation = useMutation({
mutationKey: ['tenant-invite:accept'],
mutationFn: async (data: { invite: string }) => {
await api.tenantInviteAccept(data);
mutationFn: async (data: {
tenantId: string;
inner: { invite: string };
}) => {
await api.tenantInviteAccept(data.inner);
return data.tenantId;
},
onSuccess: async () => {
// TODO: if there's more than 1 invite, stay on the screen
navigate('/');
onSuccess: async (tenantId: string) => {
try {
const memberships = await api.tenantMembershipsList();
const foundTenant = memberships.data.rows?.find(
(m) => m.tenant?.metadata.id === tenantId,
)?.tenant;
switch (foundTenant?.version) {
case TenantVersion.V0:
navigate(`/workflow-runs?tenant=${tenantId}`);
break;
case TenantVersion.V1:
navigate(`/v1/workflow-runs?tenant=${tenantId}`);
break;
default:
navigate('/');
break;
}
} catch (e) {
navigate('/');
}
},
onError: handleApiError,
});
@@ -92,7 +115,10 @@ export default function TenantInvites() {
className="w-full"
onClick={() => {
acceptMutation.mutate({
invite: invite.metadata.id,
tenantId: invite.tenantId,
inner: {
invite: invite.metadata.id,
},
});
}}
>

View File

@@ -560,7 +560,7 @@ func createControllerLayer(dc *database.Layer, cf *server.ServerConfigFile, vers
cf.Runtime.Monitoring.TLSRootCAFile = cf.TLS.TLSRootCAFile
}
internalClientFactory, err := loadInternalClient(&l, &cf.InternalClient, cf.TLS, cf.Runtime.GRPCBroadcastAddress)
internalClientFactory, err := loadInternalClient(&l, &cf.InternalClient, cf.TLS, cf.Runtime.GRPCBroadcastAddress, cf.Runtime.GRPCInsecure)
if err != nil {
return nil, nil, fmt.Errorf("could not load internal client: %w", err)
@@ -688,7 +688,7 @@ func loadEncryptionSvc(cf *server.ServerConfigFile) (encryption.EncryptionServic
return encryptionSvc, nil
}
func loadInternalClient(l *zerolog.Logger, conf *server.InternalClientTLSConfigFile, baseServerTLS shared.TLSConfigFile, grpcBroadcastAddress string) (*clientv1.GRPCClientFactory, error) {
func loadInternalClient(l *zerolog.Logger, conf *server.InternalClientTLSConfigFile, baseServerTLS shared.TLSConfigFile, grpcBroadcastAddress string, grpcInsecure bool) (*clientv1.GRPCClientFactory, error) {
// get gRPC broadcast address
broadcastAddress := grpcBroadcastAddress
@@ -714,6 +714,10 @@ func loadInternalClient(l *zerolog.Logger, conf *server.InternalClientTLSConfigF
if conf.InheritBase {
base = baseServerTLS
if grpcInsecure {
base.TLSStrategy = "none"
}
} else {
base = conf.Base
}

View File

@@ -46,13 +46,16 @@ WHERE
-- name: ListTenantInvitesByEmail :many
SELECT
*
iv.*,
t."name" as "tenantName"
FROM
"TenantInviteLink"
"TenantInviteLink" iv
JOIN
"Tenant" t ON iv."tenantId" = t."id"
WHERE
"inviteeEmail" = @inviteeEmail::text
AND "status" = 'PENDING'
AND "expires" > now();
iv."inviteeEmail" = @inviteeEmail::text
AND iv."status" = 'PENDING'
AND iv."expires" > now();
-- name: ListInvitesByTenantId :many
SELECT

View File

@@ -207,24 +207,40 @@ func (q *Queries) ListInvitesByTenantId(ctx context.Context, db DBTX, arg ListIn
const listTenantInvitesByEmail = `-- name: ListTenantInvitesByEmail :many
SELECT
id, "createdAt", "updatedAt", "tenantId", "inviterEmail", "inviteeEmail", expires, status, role
iv.id, iv."createdAt", iv."updatedAt", iv."tenantId", iv."inviterEmail", iv."inviteeEmail", iv.expires, iv.status, iv.role,
t."name" as "tenantName"
FROM
"TenantInviteLink"
"TenantInviteLink" iv
JOIN
"Tenant" t ON iv."tenantId" = t."id"
WHERE
"inviteeEmail" = $1::text
AND "status" = 'PENDING'
AND "expires" > now()
iv."inviteeEmail" = $1::text
AND iv."status" = 'PENDING'
AND iv."expires" > now()
`
func (q *Queries) ListTenantInvitesByEmail(ctx context.Context, db DBTX, inviteeemail string) ([]*TenantInviteLink, error) {
type ListTenantInvitesByEmailRow struct {
ID pgtype.UUID `json:"id"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
TenantId pgtype.UUID `json:"tenantId"`
InviterEmail string `json:"inviterEmail"`
InviteeEmail string `json:"inviteeEmail"`
Expires pgtype.Timestamp `json:"expires"`
Status InviteLinkStatus `json:"status"`
Role TenantMemberRole `json:"role"`
TenantName string `json:"tenantName"`
}
func (q *Queries) ListTenantInvitesByEmail(ctx context.Context, db DBTX, inviteeemail string) ([]*ListTenantInvitesByEmailRow, error) {
rows, err := db.Query(ctx, listTenantInvitesByEmail, inviteeemail)
if err != nil {
return nil, err
}
defer rows.Close()
var items []*TenantInviteLink
var items []*ListTenantInvitesByEmailRow
for rows.Next() {
var i TenantInviteLink
var i ListTenantInvitesByEmailRow
if err := rows.Scan(
&i.ID,
&i.CreatedAt,
@@ -235,6 +251,7 @@ func (q *Queries) ListTenantInvitesByEmail(ctx context.Context, db DBTX, invitee
&i.Expires,
&i.Status,
&i.Role,
&i.TenantName,
); err != nil {
return nil, err
}

View File

@@ -98,7 +98,7 @@ func (r *tenantInviteRepository) GetTenantInvite(ctx context.Context, id string)
)
}
func (r *tenantInviteRepository) ListTenantInvitesByEmail(ctx context.Context, email string) ([]*dbsqlc.TenantInviteLink, error) {
func (r *tenantInviteRepository) ListTenantInvitesByEmail(ctx context.Context, email string) ([]*dbsqlc.ListTenantInvitesByEmailRow, error) {
return r.queries.ListTenantInvitesByEmail(
ctx,
r.pool,

View File

@@ -49,7 +49,7 @@ type TenantInviteRepository interface {
// ListTenantInvitesByEmail returns the list of tenant invites for the given invitee email for invites
// which are not expired
ListTenantInvitesByEmail(ctx context.Context, email string) ([]*dbsqlc.TenantInviteLink, error)
ListTenantInvitesByEmail(ctx context.Context, email string) ([]*dbsqlc.ListTenantInvitesByEmailRow, error)
// ListTenantInvitesByTenantId returns the list of tenant invites for the given tenant id
ListTenantInvitesByTenantId(ctx context.Context, tenantId string, opts *ListTenantInvitesOpts) ([]*dbsqlc.TenantInviteLink, error)