Skip to content

Commit 4b56968

Browse files
author
FusionAuth Automation
committed
sync from monorepo f925969b3a30
1 parent 8d80e92 commit 4b56968

2 files changed

Lines changed: 83 additions & 14 deletions

File tree

pkg/fusionauth/Client.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,18 @@ type restClient struct {
221221
Uri *url.URL
222222
}
223223

224+
type readerWithCloser struct {
225+
io.Reader
226+
closer io.Closer
227+
}
228+
229+
func (r *readerWithCloser) Close() error {
230+
if r.closer != nil {
231+
return r.closer.Close()
232+
}
233+
return nil
234+
}
235+
224236
func (c *FusionAuthClient) Start(responseRef interface{}, errorRef interface{}) *restClient {
225237
return c.StartAnonymous(responseRef, errorRef).WithAuthorization(c.APIKey)
226238
}
@@ -256,6 +268,11 @@ func (rc *restClient) Do(ctx context.Context) error {
256268
// Bodies exceeding MaxBodyBufferSize cannot be safely buffered; in that case the
257269
// stream is left intact and retries are disabled for this request.
258270
if canRetryRequest && rc.Body != nil {
271+
var bodyCloser io.Closer
272+
if closer, ok := rc.Body.(io.Closer); ok {
273+
bodyCloser = closer
274+
}
275+
259276
maxBuffer := rc.RetryConfiguration.MaxBodyBufferSize
260277
if maxBuffer == 0 {
261278
maxBuffer = 1 << 20 // 1 MiB default
@@ -272,9 +289,21 @@ func (rc *restClient) Do(ctx context.Context) error {
272289
}
273290
if int64(len(b)) > maxBuffer {
274291
// Body exceeds the buffer limit; reconstruct the stream and skip retries.
275-
rc.Body = io.MultiReader(bytes.NewReader(b), rc.Body)
292+
body := io.Reader(io.MultiReader(bytes.NewReader(b), rc.Body))
293+
if bodyCloser != nil {
294+
body = &readerWithCloser{
295+
Reader: body,
296+
closer: bodyCloser,
297+
}
298+
}
299+
rc.Body = body
276300
canRetryRequest = false
277301
} else {
302+
if bodyCloser != nil {
303+
if err := bodyCloser.Close(); err != nil {
304+
return err
305+
}
306+
}
278307
rc.bodyBytes = b
279308
rc.Body = nil
280309
}
@@ -327,10 +356,10 @@ func (rc *restClient) Do(ctx context.Context) error {
327356
return err
328357
}
329358
if rc.Debug || attempt < maxAttempts-1 {
330-
// Fast path: if the status code alone warrants a retry and no RetryFunction
331-
// needs to inspect the body, drain and discard it to avoid buffering.
359+
// Fast path: if the status code alone warrants a retry, drain and discard
360+
// the body so high-volume retries do not buffer unused payloads.
332361
if !rc.Debug && attempt < maxAttempts-1 {
333-
if _, ok := rc.RetryConfiguration.RetryableStatusCodes[resp.StatusCode]; ok && rc.RetryConfiguration.RetryFunction == nil {
362+
if rc.isRetryableStatusCode(resp.StatusCode) {
334363
io.Copy(io.Discard, resp.Body)
335364
resp.Body.Close()
336365
continue
@@ -401,7 +430,7 @@ func (rc *restClient) isMethodRetryable() bool {
401430

402431
// shouldRetry returns true if the status code or body indicates a retryable failure.
403432
func (rc *restClient) shouldRetry(statusCode int, body []byte) bool {
404-
if _, ok := rc.RetryConfiguration.RetryableStatusCodes[statusCode]; ok {
433+
if rc.isRetryableStatusCode(statusCode) {
405434
return true
406435
}
407436
if rc.RetryConfiguration.RetryFunction != nil {
@@ -410,6 +439,11 @@ func (rc *restClient) shouldRetry(statusCode int, body []byte) bool {
410439
return false
411440
}
412441

442+
func (rc *restClient) isRetryableStatusCode(statusCode int) bool {
443+
_, ok := rc.RetryConfiguration.RetryableStatusCodes[statusCode]
444+
return ok
445+
}
446+
413447
func (rc *restClient) WithAuthorization(key string) *restClient {
414448
if key != "" {
415449
rc.WithHeader("Authorization", key)

pkg/fusionauth/Domain.go

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ type ApplicationMultiFactorConfiguration struct {
433433
LoginPolicy MultiFactorLoginPolicy `json:"loginPolicy,omitempty"`
434434
Sms MultiFactorSMSTemplate `json:"sms,omitempty"`
435435
TrustPolicy ApplicationMultiFactorTrustPolicy `json:"trustPolicy,omitempty"`
436+
Voice MultiFactorVoiceTemplate `json:"voice,omitempty"`
436437
}
437438

438439
type MultiFactorEmailTemplate struct {
@@ -443,6 +444,10 @@ type MultiFactorSMSTemplate struct {
443444
TemplateId string `json:"templateId,omitempty"`
444445
}
445446

447+
type MultiFactorVoiceTemplate struct {
448+
TemplateId string `json:"templateId,omitempty"`
449+
}
450+
446451
/**
447452
* @author Daniel DeGroff
448453
*/
@@ -961,6 +966,7 @@ type BaseMessengerConfiguration struct {
961966
Id string `json:"id,omitempty"`
962967
InsertInstant int64 `json:"insertInstant,omitempty"`
963968
LastUpdateInstant int64 `json:"lastUpdateInstant,omitempty"`
969+
MessageTypes []MessageType `json:"messageTypes,omitempty"`
964970
Name string `json:"name,omitempty"`
965971
Transport string `json:"transport,omitempty"`
966972
Type MessengerType `json:"type,omitempty"`
@@ -4422,7 +4428,8 @@ func (e MessageType) String() string {
44224428
}
44234429

44244430
const (
4425-
MessageType_SMS MessageType = "SMS"
4431+
MessageType_SMS MessageType = "SMS"
4432+
MessageType_Voice MessageType = "Voice"
44264433
)
44274434

44284435
/**
@@ -4447,6 +4454,7 @@ func (b *MessengerResponse) SetStatus(status int) {
44474454

44484455
/**
44494456
* @author Daniel DeGroff
4457+
* @deprecated since 1.65.0, use {@code MessageType} instead
44504458
*/
44514459
type MessengerTransport struct {
44524460
}
@@ -5107,8 +5115,9 @@ type PreviewMessageTemplateRequest struct {
51075115
*/
51085116
type PreviewMessageTemplateResponse struct {
51095117
BaseHTTPResponse
5110-
Errors Errors `json:"errors,omitempty"`
5111-
Message SMSMessage `json:"message,omitempty"`
5118+
Errors Errors `json:"errors,omitempty"`
5119+
Message SMSMessage `json:"message,omitempty"`
5120+
PreviewMessage Message `json:"previewMessage,omitempty"`
51125121
}
51135122

51145123
func (b *PreviewMessageTemplateResponse) SetStatus(status int) {
@@ -6346,6 +6355,7 @@ type TenantMultiFactorConfiguration struct {
63466355
Email MultiFactorEmailMethod `json:"email,omitempty"`
63476356
LoginPolicy MultiFactorLoginPolicy `json:"loginPolicy,omitempty"`
63486357
Sms MultiFactorSMSMethod `json:"sms,omitempty"`
6358+
Voice MultiFactorVoiceMethod `json:"voice,omitempty"`
63496359
}
63506360

63516361
type MultiFactorAuthenticatorMethod struct {
@@ -6366,6 +6376,12 @@ type MultiFactorSMSMethod struct {
63666376
TemplateId string `json:"templateId,omitempty"`
63676377
}
63686378

6379+
type MultiFactorVoiceMethod struct {
6380+
Enableable
6381+
MessengerId string `json:"messengerId,omitempty"`
6382+
TemplateId string `json:"templateId,omitempty"`
6383+
}
6384+
63696385
/**
63706386
* Hold tenant phone configuration for passwordless and verification cases.
63716387
*
@@ -6954,12 +6970,13 @@ func (b *TwoFactorResponse) SetStatus(status int) {
69546970
* @author Daniel DeGroff
69556971
*/
69566972
type TwoFactorSendRequest struct {
6957-
ApplicationId string `json:"applicationId,omitempty"`
6958-
Email string `json:"email,omitempty"`
6959-
Method string `json:"method,omitempty"`
6960-
MethodId string `json:"methodId,omitempty"`
6961-
MobilePhone string `json:"mobilePhone,omitempty"`
6962-
UserId string `json:"userId,omitempty"`
6973+
ApplicationId string `json:"applicationId,omitempty"`
6974+
Email string `json:"email,omitempty"`
6975+
MessageType MessageType `json:"messageType,omitempty"`
6976+
Method string `json:"method,omitempty"`
6977+
MethodId string `json:"methodId,omitempty"`
6978+
MobilePhone string `json:"mobilePhone,omitempty"`
6979+
UserId string `json:"userId,omitempty"`
69636980
}
69646981

69656982
/**
@@ -8125,6 +8142,24 @@ func (b *VersionResponse) SetStatus(status int) {
81258142
b.StatusCode = status
81268143
}
81278144

8145+
/**
8146+
* @author Daniel King
8147+
*/
8148+
type VoiceMessage struct {
8149+
Locale string `json:"locale,omitempty"`
8150+
Message string `json:"message,omitempty"`
8151+
PhoneNumber string `json:"phoneNumber,omitempty"`
8152+
}
8153+
8154+
/**
8155+
* @author Daniel King
8156+
*/
8157+
type VoiceMessageTemplate struct {
8158+
MessageTemplate
8159+
DefaultTemplate string `json:"defaultTemplate,omitempty"`
8160+
LocalizedTemplates map[string]string `json:"localizedTemplates,omitempty"`
8161+
}
8162+
81288163
/**
81298164
* API response for completing WebAuthn assertion
81308165
*

0 commit comments

Comments
 (0)