57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
|
package token
|
||
|
|
||
|
import (
|
||
|
"github.com/pkg/errors"
|
||
|
"gopkg.in/square/go-jose.v2"
|
||
|
"gopkg.in/square/go-jose.v2/jwt"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
jwtIssuer = "hydra-passwordless"
|
||
|
)
|
||
|
|
||
|
type privateClaims struct {
|
||
|
Challenge string `json:"challenge"`
|
||
|
}
|
||
|
|
||
|
func Generate(signingKey, encryptionKey, email, challenge string) (string, error) {
|
||
|
sig, err := jose.NewSigner(
|
||
|
jose.SigningKey{
|
||
|
Algorithm: jose.HS256,
|
||
|
Key: []byte(signingKey),
|
||
|
},
|
||
|
(&jose.SignerOptions{}).WithType("JWT"),
|
||
|
)
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "could not create jwt signer")
|
||
|
}
|
||
|
|
||
|
enc, err := jose.NewEncrypter(
|
||
|
jose.A256GCM,
|
||
|
jose.Recipient{
|
||
|
Algorithm: jose.DIRECT,
|
||
|
Key: []byte(encryptionKey),
|
||
|
},
|
||
|
(&jose.EncrypterOptions{}).WithType("JWT").WithContentType("JWT"))
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "could not create jwt encrypter")
|
||
|
}
|
||
|
|
||
|
claims := jwt.Claims{
|
||
|
Subject: email,
|
||
|
Issuer: jwtIssuer,
|
||
|
Audience: jwt.Audience{jwtIssuer},
|
||
|
}
|
||
|
|
||
|
privateClaims := privateClaims{
|
||
|
Challenge: challenge,
|
||
|
}
|
||
|
|
||
|
raw, err := jwt.SignedAndEncrypted(sig, enc).Claims(claims).Claims(privateClaims).CompactSerialize()
|
||
|
if err != nil {
|
||
|
return "", errors.Wrap(err, "could not sign and encrypt jwt")
|
||
|
}
|
||
|
|
||
|
return raw, nil
|
||
|
}
|