69 lines
1.5 KiB
Go
69 lines
1.5 KiB
Go
package logic
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
deviceentity "spark-server/internal/module/device/entity"
|
|
)
|
|
|
|
// FingerprintInput is the physical identity for one login/register.
|
|
type FingerprintInput struct {
|
|
DeviceType deviceentity.DeviceType
|
|
IDFV string
|
|
AndroidID string
|
|
}
|
|
|
|
func fingerprintHash(in FingerprintInput) (string, error) {
|
|
if !in.DeviceType.Valid() {
|
|
return "", fmt.Errorf("device_type")
|
|
}
|
|
idfv := strings.TrimSpace(in.IDFV)
|
|
androidID := strings.TrimSpace(in.AndroidID)
|
|
var tail string
|
|
switch in.DeviceType {
|
|
case deviceentity.TypeIOS, deviceentity.TypeMacOS:
|
|
if idfv == "" {
|
|
return "", fmt.Errorf("idfv")
|
|
}
|
|
tail = idfv
|
|
case deviceentity.TypeAndroid, deviceentity.TypeHarmony:
|
|
if androidID == "" {
|
|
return "", fmt.Errorf("android_id")
|
|
}
|
|
tail = androidID
|
|
default:
|
|
switch {
|
|
case idfv != "":
|
|
tail = idfv
|
|
case androidID != "":
|
|
tail = androidID
|
|
default:
|
|
return "", fmt.Errorf("device_id")
|
|
}
|
|
}
|
|
payload := fmt.Sprintf("%d:%s", in.DeviceType, tail)
|
|
sum := sha256.Sum256([]byte(payload))
|
|
return hex.EncodeToString(sum[:]), nil
|
|
}
|
|
|
|
// DeviceIDFromFingerprint derives the stable business device id.
|
|
func DeviceIDFromFingerprint(in FingerprintInput) (uint64, string, error) {
|
|
hash, err := fingerprintHash(in)
|
|
if err != nil {
|
|
return 0, "", err
|
|
}
|
|
sum := sha256.Sum256([]byte(hash))
|
|
id := binary.BigEndian.Uint64(sum[:8])
|
|
if id == 0 {
|
|
id = binary.BigEndian.Uint64(sum[1:9])
|
|
}
|
|
if id == 0 {
|
|
id = 1
|
|
}
|
|
return id, hash, nil
|
|
}
|