package gatewayauthsessionmail_test import ( "context" "crypto/ed25519" "net/http" "net/url" "testing" gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1" "github.com/stretchr/testify/require" ) func TestGatewayAuthsessionMailSendAndConfirmWithRealMailService(t *testing.T) { h := newGatewayAuthsessionMailHarness(t) clientPrivateKey := newClientPrivateKey("real-mail") challengeID := h.sendChallengeWithAcceptLanguage(t, testEmail, "fr-FR, en;q=0.8") list := h.eventuallyListDeliveries(t, url.Values{ "source": []string{"authsession"}, "status": []string{"suppressed"}, "recipient": []string{testEmail}, "template_id": []string{"auth.login_code"}, }) require.Len(t, list.Items, 1) require.Equal(t, "authsession", list.Items[0].Source) require.Equal(t, "suppressed", list.Items[0].Status) require.Equal(t, "auth.login_code", list.Items[0].TemplateID) require.Equal(t, "fr-FR", list.Items[0].Locale) require.Equal(t, []string{testEmail}, list.Items[0].To) detail := h.getDelivery(t, list.Items[0].DeliveryID) require.Equal(t, "authsession", detail.Source) require.Equal(t, "suppressed", detail.Status) require.Equal(t, "auth.login_code", detail.TemplateID) require.Equal(t, "fr-FR", detail.Locale) require.False(t, detail.LocaleFallbackUsed) require.Equal(t, []string{testEmail}, detail.To) require.NotEmpty(t, detail.IdempotencyKey) code := templateVariableString(t, detail.TemplateVariables, "code") confirm := h.confirmCode(t, challengeID, code, clientPrivateKey) require.Equal(t, http.StatusOK, confirm.StatusCode, confirm.Body) var confirmBody confirmEmailCodeResponse require.NoError(t, decodeStrictJSONPayload([]byte(confirm.Body), &confirmBody)) require.NotEmpty(t, confirmBody.DeviceSessionID) record := h.waitForGatewaySession(t, confirmBody.DeviceSessionID) require.Equal(t, gatewaySessionRecord{ DeviceSessionID: confirmBody.DeviceSessionID, UserID: "user-1", ClientPublicKey: encodePublicKey(clientPrivateKey.Public().(ed25519.PublicKey)), Status: "active", }, record) ensureCalls := h.userStub.EnsureCalls() require.Len(t, ensureCalls, 1) require.Equal(t, testEmail, ensureCalls[0].Email) require.Equal(t, "fr-FR", ensureCalls[0].PreferredLanguage) require.Equal(t, testTimeZone, ensureCalls[0].TimeZone) conn := h.dialGateway(t) client := gatewayv1.NewEdgeGatewayClient(conn) stream, err := client.SubscribeEvents(context.Background(), newSubscribeEventsRequest(confirmBody.DeviceSessionID, "request-bootstrap", clientPrivateKey)) require.NoError(t, err) event, err := stream.Recv() require.NoError(t, err) assertBootstrapEvent(t, event, h.responseSignerPublicKey, "request-bootstrap") } func TestGatewayAuthsessionMailUnavailablePassesThroughGatewaySurface(t *testing.T) { h := newGatewayAuthsessionMailHarness(t) h.stopMail(t) response := postJSONValue(t, h.gatewayPublicURL+gatewaySendEmailCodePath, map[string]string{ "email": testEmail, }) require.Equal(t, http.StatusServiceUnavailable, response.StatusCode) require.JSONEq(t, `{"error":{"code":"service_unavailable","message":"service is unavailable"}}`, response.Body) } func TestGatewayAuthsessionMailAuthCodeBypassesNotificationStream(t *testing.T) { h := newGatewayAuthsessionMailHarness(t) h.sendChallengeWithAcceptLanguage(t, testEmail, "en") list := h.eventuallyListDeliveries(t, url.Values{ "source": []string{"authsession"}, "recipient": []string{testEmail}, "template_id": []string{"auth.login_code"}, }) require.Len(t, list.Items, 1) require.Equal(t, "authsession", list.Items[0].Source) require.Equal(t, "auth.login_code", list.Items[0].TemplateID) length, err := h.redis.XLen(context.Background(), "notification:intents").Result() require.NoError(t, err) require.Zero(t, length) }