verifyInteraction implements message verification of the discord interactions api signing algorithm, as documented here: https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
(ctxLogger telemetry.Logger, c fiber.Ctx)
| 421 | // signing algorithm, as documented here: |
| 422 | // https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization |
| 423 | func (h *DiscordHandler) verifyInteraction(ctxLogger telemetry.Logger, c fiber.Ctx) bool { |
| 424 | var msg bytes.Buffer |
| 425 | |
| 426 | signature := c.Get("X-Signature-Ed25519") |
| 427 | if signature == "" { |
| 428 | ctxLogger.Info("X-Signature-Ed25519 header is empty") |
| 429 | return false |
| 430 | } |
| 431 | |
| 432 | sig, err := hex.DecodeString(signature) |
| 433 | if err != nil { |
| 434 | ctxLogger.Info(fmt.Sprintf("cannot decode X-Signature-Ed25519 [%s]", signature)) |
| 435 | return false |
| 436 | } |
| 437 | |
| 438 | if len(sig) != ed25519.SignatureSize { |
| 439 | ctxLogger.Info(fmt.Sprintf("invalid signature size [%d]", len(sig))) |
| 440 | return false |
| 441 | } |
| 442 | |
| 443 | timestamp := c.Get("X-Signature-Timestamp") |
| 444 | if timestamp == "" { |
| 445 | ctxLogger.Info("X-Signature-Timestamp header is empty") |
| 446 | return false |
| 447 | } |
| 448 | |
| 449 | msg.WriteString(timestamp) |
| 450 | msg.Write(c.Body()) |
| 451 | |
| 452 | key, err := hex.DecodeString(os.Getenv("DISCORD_PUBLIC_KEY")) |
| 453 | if err != nil { |
| 454 | ctxLogger.Error(stacktrace.Propagate(err, "cannot decode DISCORD_PUBLIC_KEY env variable [%s]", os.Getenv("DISCORD_PUBLIC_KEY"))) |
| 455 | return false |
| 456 | } |
| 457 | |
| 458 | return ed25519.Verify(key, msg.Bytes(), sig) |
| 459 | } |