init repo
This commit is contained in:
85
rpc/apple.go
Normal file
85
rpc/apple.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/Timothylock/go-signin-with-apple/apple"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
type AppleClient struct {
|
||||
*apple.Client
|
||||
teamID string
|
||||
clientID string
|
||||
keyID string
|
||||
secret string
|
||||
}
|
||||
|
||||
// GenerateClientSecret generates a new client secret, all fields are required, no http request, fully local logic
|
||||
func (a *AppleClient) GenerateClientSecret() (string, error) {
|
||||
token := &jwt.Token{
|
||||
Header: map[string]interface{}{
|
||||
"alg": "ES256",
|
||||
"kid": a.keyID,
|
||||
},
|
||||
Claims: jwt.MapClaims{
|
||||
"iss": a.teamID,
|
||||
"iat": time.Now().Unix(),
|
||||
// constraint: exp - iat <= 180 days
|
||||
"exp": time.Now().Add(24 * time.Hour).Unix(),
|
||||
"aud": "https://appleid.apple.com",
|
||||
"sub": a.clientID,
|
||||
},
|
||||
Method: jwt.SigningMethodES256,
|
||||
}
|
||||
|
||||
ecdsaKey, _ := authKeyFromBytes([]byte(a.secret))
|
||||
return token.SignedString(ecdsaKey)
|
||||
}
|
||||
|
||||
// authKeyFromBytes create private key for jwt sign
|
||||
func authKeyFromBytes(key []byte) (*ecdsa.PrivateKey, error) {
|
||||
var err error
|
||||
|
||||
var block *pem.Block
|
||||
if block, _ = pem.Decode(key); block == nil {
|
||||
return nil, errors.New("token: AuthKey must be a valid .p8 PEM file")
|
||||
}
|
||||
|
||||
var parsedKey interface{}
|
||||
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pkey *ecdsa.PrivateKey
|
||||
var ok bool
|
||||
if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
|
||||
return nil, errors.New("token: AuthKey must be of type ecdsa.PrivateKey")
|
||||
}
|
||||
|
||||
return pkey, nil
|
||||
}
|
||||
|
||||
func (a *AppleClient) VerifyAppToken(ctx context.Context, code string) (apple.ValidationResponse, error) {
|
||||
var resp apple.ValidationResponse
|
||||
clientSecret, err := a.GenerateClientSecret()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
reqBody := apple.AppValidationTokenRequest{
|
||||
ClientID: a.clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Code: code,
|
||||
}
|
||||
if err := a.Client.VerifyAppToken(ctx, reqBody, &resp); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
23
rpc/apple_test.go
Normal file
23
rpc/apple_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/nose7en/ToyBoomServer/config"
|
||||
)
|
||||
|
||||
const token = "c2fa05395f0974b798d7d9ae802a17bae.0.srvuz.8c3w4pp04rFe9CXbrtNxVg"
|
||||
|
||||
func TestAppleClient_VerifyAppToken(t *testing.T) {
|
||||
|
||||
config.InitSettings()
|
||||
|
||||
InitManager()
|
||||
|
||||
cli := GetManager().AppleCli()
|
||||
resp, err := cli.VerifyAppToken(context.Background(), token)
|
||||
|
||||
t.Error(err)
|
||||
t.Error(resp)
|
||||
}
|
||||
40
rpc/manager.go
Normal file
40
rpc/manager.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/Timothylock/go-signin-with-apple/apple"
|
||||
"github.com/nose7en/ToyBoomServer/config"
|
||||
)
|
||||
|
||||
type Manager interface {
|
||||
AppleCli() *AppleClient
|
||||
}
|
||||
|
||||
var (
|
||||
mgr Manager = (*manager)(nil)
|
||||
)
|
||||
|
||||
func GetManager() Manager {
|
||||
return mgr
|
||||
}
|
||||
|
||||
func InitManager() {
|
||||
mgr = &manager{}
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
appleCli *AppleClient
|
||||
}
|
||||
|
||||
func (m *manager) AppleCli() *AppleClient {
|
||||
if m.appleCli == nil {
|
||||
m.appleCli = &AppleClient{
|
||||
Client: apple.New(),
|
||||
teamID: config.GetSettings().AppleCfg.TeamID,
|
||||
clientID: config.GetSettings().AppleCfg.ClientID,
|
||||
keyID: config.GetSettings().AppleCfg.KeyID,
|
||||
secret: config.GetSettings().AppleCfg.Secret,
|
||||
}
|
||||
}
|
||||
|
||||
return m.appleCli
|
||||
}
|
||||
Reference in New Issue
Block a user