webauthn_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package config
  2. import (
  3. "strings"
  4. "testing"
  5. "github.com/spf13/viper"
  6. "github.com/stretchr/testify/require"
  7. )
  8. func TestValidateWebAuthnConfig(t *testing.T) {
  9. tests := []struct {
  10. name string
  11. configure func(*Config)
  12. wantError string
  13. }{
  14. {
  15. name: "valid production origin",
  16. configure: func(cfg *Config) {
  17. cfg.WebAuthn = WebAuthnConfig{
  18. Enabled: true,
  19. RPDisplayName: "Sub2API",
  20. RPID: "sub2api.example.com",
  21. RPOrigins: []string{"https://sub2api.example.com"},
  22. }
  23. },
  24. },
  25. {
  26. name: "valid localhost development origin",
  27. configure: func(cfg *Config) {
  28. cfg.WebAuthn = WebAuthnConfig{
  29. Enabled: true,
  30. RPDisplayName: "Sub2API Dev",
  31. RPID: "localhost",
  32. RPOrigins: []string{"http://localhost:5173"},
  33. }
  34. },
  35. },
  36. {
  37. name: "missing relying party id",
  38. configure: func(cfg *Config) {
  39. cfg.WebAuthn = WebAuthnConfig{
  40. Enabled: true,
  41. RPDisplayName: "Sub2API",
  42. RPOrigins: []string{"https://sub2api.example.com"},
  43. }
  44. },
  45. wantError: "webauthn.rp_id",
  46. },
  47. {
  48. name: "relying party id contains scheme",
  49. configure: func(cfg *Config) {
  50. cfg.WebAuthn = WebAuthnConfig{
  51. Enabled: true,
  52. RPDisplayName: "Sub2API",
  53. RPID: "https://sub2api.example.com",
  54. RPOrigins: []string{"https://sub2api.example.com"},
  55. }
  56. },
  57. wantError: "domain without scheme",
  58. },
  59. {
  60. name: "non-local insecure origin",
  61. configure: func(cfg *Config) {
  62. cfg.WebAuthn = WebAuthnConfig{
  63. Enabled: true,
  64. RPDisplayName: "Sub2API",
  65. RPID: "sub2api.example.com",
  66. RPOrigins: []string{"http://sub2api.example.com"},
  67. }
  68. },
  69. wantError: "must use HTTPS",
  70. },
  71. {
  72. name: "origin outside relying party id",
  73. configure: func(cfg *Config) {
  74. cfg.WebAuthn = WebAuthnConfig{
  75. Enabled: true,
  76. RPDisplayName: "Sub2API",
  77. RPID: "example.com",
  78. RPOrigins: []string{"https://example.net"},
  79. }
  80. },
  81. wantError: "not within relying party ID",
  82. },
  83. }
  84. for _, tt := range tests {
  85. t.Run(tt.name, func(t *testing.T) {
  86. viper.Reset()
  87. t.Setenv("JWT_SECRET", strings.Repeat("x", 32))
  88. cfg, err := Load()
  89. require.NoError(t, err)
  90. tt.configure(cfg)
  91. err = cfg.Validate()
  92. if tt.wantError == "" {
  93. require.NoError(t, err)
  94. } else {
  95. require.ErrorContains(t, err, tt.wantError)
  96. }
  97. })
  98. }
  99. }