resolvePreLoginEmailSetting returns the EMAIL setting to use for unauthenticated flows (email-code sign-in, password reset). Resolution order: 1. If `workspaceID` is provided, use that workspace's EMAIL setting. The frontend resolves the workspace (from the route query or actuator context) and alway
( ctx context.Context, stores *store.Store, workspaceID string, )
| 1672 | // 2. EMAIL_CONFIG env var — deployment-wide fallback for SaaS brand-new signup, where |
| 1673 | // the caller has no workspace context yet (no pre-invite, no workspace in the URL). |
| 1674 | func resolvePreLoginEmailSetting( |
| 1675 | ctx context.Context, |
| 1676 | stores *store.Store, |
| 1677 | workspaceID string, |
| 1678 | ) (*storepb.EmailSetting, error) { |
| 1679 | if workspaceID != "" { |
| 1680 | emailSettingMsg, err := stores.GetSetting(ctx, workspaceID, storepb.SettingName_EMAIL) |
| 1681 | if err != nil { |
| 1682 | return nil, errors.Wrap(err, "failed to load email setting") |
| 1683 | } |
| 1684 | if emailSettingMsg == nil { |
| 1685 | return nil, nil |
| 1686 | } |
| 1687 | es, ok := emailSettingMsg.Value.(*storepb.EmailSetting) |
| 1688 | if !ok { |
| 1689 | return nil, nil |
| 1690 | } |
| 1691 | return es, nil |
| 1692 | } |
| 1693 | |
| 1694 | if raw := os.Getenv("EMAIL_CONFIG"); raw != "" { |
| 1695 | emailSetting := &storepb.EmailSetting{} |
| 1696 | if err := common.ProtojsonUnmarshaler.Unmarshal([]byte(raw), emailSetting); err != nil { |
| 1697 | return nil, errors.Wrap(err, "failed to parse EMAIL_CONFIG") |
| 1698 | } |
| 1699 | return emailSetting, nil |
| 1700 | } |
| 1701 | |
| 1702 | return nil, nil |
| 1703 | } |
| 1704 | |
| 1705 | // sendEmailVerificationCode generates a code, atomically stores its hash (subject to cooldown), |
| 1706 | // and emails the plain code. Returns nil on a successful send as well as on silent-skip paths |
no test coverage detected