Unverified Commit 64d36359 authored by Simon Esposito's avatar Simon Esposito Committed by GitHub
Browse files

Add Apple IAP validation secret override. (#640)

Allow PurchaseValidateApple to be called with an optional parameter to override the configured Apple shared password.
Fix JS runtime storageList bug
parent f967c718
Loading
Loading
Loading
Loading
+1 −1
Changes for go.mod: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ require (
	github.com/gorilla/mux v1.8.0
	github.com/gorilla/websocket v1.4.2
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0
	github.com/heroiclabs/nakama-common v1.14.1-0.20210628193431-8ff23c118581
	github.com/heroiclabs/nakama-common v1.14.1-0.20210707135714-ed381a338271
	github.com/jackc/pgconn v1.8.1
	github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451
	github.com/jackc/pgtype v1.7.0
+2 −4
Changes for go.sum: 2 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -310,10 +310,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/heroiclabs/nakama-common v1.14.1-0.20210618160619-e507376361e7 h1:7IkqA4MrM5yHZEUdeTj4kl288YqZ2UPD/hEN4XbJ3KY=
github.com/heroiclabs/nakama-common v1.14.1-0.20210618160619-e507376361e7/go.mod h1:jzIGV5bI45ALRQFzHPkJn4Z0tV+xhtho1+pZhOXVAsk=
github.com/heroiclabs/nakama-common v1.14.1-0.20210628193431-8ff23c118581 h1:pt7FlYhHLRVastJWZnOauzcY00FsPiF3IgT6Ey+h604=
github.com/heroiclabs/nakama-common v1.14.1-0.20210628193431-8ff23c118581/go.mod h1:jzIGV5bI45ALRQFzHPkJn4Z0tV+xhtho1+pZhOXVAsk=
github.com/heroiclabs/nakama-common v1.14.1-0.20210707135714-ed381a338271 h1:iZt1PkdjXKYg7bSFw2X5oEUf5m7NFuku7nTJZibGNOY=
github.com/heroiclabs/nakama-common v1.14.1-0.20210707135714-ed381a338271/go.mod h1:jzIGV5bI45ALRQFzHPkJn4Z0tV+xhtho1+pZhOXVAsk=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+9 −3
Changes for server/runtime_go_nakama.go: 9 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -1947,10 +1947,16 @@ func (n *RuntimeGoNakamaModule) TournamentRecordsHaystack(ctx context.Context, i
	return TournamentRecordsHaystack(ctx, n.logger, n.db, n.leaderboardCache, n.leaderboardRankCache, id, owner, limit, expiry)
}

func (n *RuntimeGoNakamaModule) PurchaseValidateApple(ctx context.Context, userID, receipt string) (*api.ValidatePurchaseResponse, error) {
	if n.config.GetIAP().Apple.SharedPassword == "" {
func (n *RuntimeGoNakamaModule) PurchaseValidateApple(ctx context.Context, userID, receipt string, passwordOverride ...string) (*api.ValidatePurchaseResponse, error) {
	if n.config.GetIAP().Apple.SharedPassword == "" && len(passwordOverride) == 0 {
		return nil, errors.New("Apple IAP is not configured.")
	}
	password := n.config.GetIAP().Apple.SharedPassword
	if len(passwordOverride) > 1 {
		return nil, errors.New("Expects a single password override parameter")
	} else if len(passwordOverride) == 1 {
		password = passwordOverride[0]
	}

	uid, err := uuid.FromString(userID)
	if err != nil {
@@ -1961,7 +1967,7 @@ func (n *RuntimeGoNakamaModule) PurchaseValidateApple(ctx context.Context, userI
		return nil, errors.New("receipt cannot be empty string")
	}

	validation, err := ValidatePurchasesApple(ctx, n.logger, n.db, uid, n.config.GetIAP().Apple.SharedPassword, receipt)
	validation, err := ValidatePurchasesApple(ctx, n.logger, n.db, uid, password, receipt)
	if err != nil {
		return nil, err
	}
+28 −19
Changes for server/runtime_javascript_nakama.go: 28 added lines, 19 removed lines.
Original line number Diff line number Diff line
@@ -3231,31 +3231,32 @@ func (n *runtimeJavascriptNakamaModule) walletLedgerList(r *goja.Runtime) func(g

func (n *runtimeJavascriptNakamaModule) storageList(r *goja.Runtime) func(goja.FunctionCall) goja.Value {
	return func(f goja.FunctionCall) goja.Value {
		userIDString := ""
		if f.Argument(0) != goja.Undefined() {
			userIDString = getJsString(r, f.Argument(0))
		}
		uid, err := uuid.FromString(userIDString)
		var uid *uuid.UUID
		if f.Argument(0) != goja.Undefined() && f.Argument(0) != goja.Null() {
			userIDString := getJsString(r, f.Argument(0))
			u, err := uuid.FromString(userIDString)
			if err != nil {
				panic(r.NewTypeError("expects empty or valid user id"))
			}
			uid = &u
		}

		collection := ""
		if f.Argument(1) != goja.Undefined() {
		if f.Argument(1) != goja.Undefined() && f.Argument(1) != goja.Null() {
			collection = getJsString(r, f.Argument(1))
		}

		limit := 100
		if f.Argument(2) != goja.Undefined() {
		if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() {
			limit = int(getJsInt(r, f.Argument(2)))
		}

		cursor := ""
		if f.Argument(3) != goja.Undefined() {
		if f.Argument(3) != goja.Undefined() && f.Argument(3) != goja.Null() {
			cursor = getJsString(r, f.Argument(3))
		}

		objectList, _, err := StorageListObjects(context.Background(), n.logger, n.db, uuid.Nil, &uid, collection, limit, cursor)
		objectList, _, err := StorageListObjects(context.Background(), n.logger, n.db, uuid.Nil, uid, collection, limit, cursor)

		objects := make([]interface{}, 0, len(objectList.Objects))
		for _, o := range objectList.Objects {
@@ -4115,7 +4116,7 @@ func (n *runtimeJavascriptNakamaModule) leaderboardRecordsList(r *goja.Runtime)
		var ownerIds []string
		owners := f.Argument(1)
		if owners != nil {
			if owners == goja.Undefined() {
			if owners == goja.Undefined() || owners == goja.Null() {
				panic(r.NewTypeError("expects an array of owner ids or null"))
			}
			ownersSlice, ok := owners.Export().([]interface{})
@@ -4128,26 +4129,29 @@ func (n *runtimeJavascriptNakamaModule) leaderboardRecordsList(r *goja.Runtime)
				if !ok {
					panic(r.NewTypeError("expects a valid owner string"))
				}
				if _, err := uuid.FromString(ownerStr); err != nil {
					panic(r.NewTypeError("expects a valid owner id"))
				}
				ownerIds = append(ownerIds, ownerStr)
			}
		}

		limitNumber := 0
		if f.Argument(2) != goja.Undefined() {
			limitNumber = int(getJsInt(r, f.Argument(2)))
		var limitNumber int32
		if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() {
			limitNumber = int32(getJsInt(r, f.Argument(2)))
		}
		var limit *wrapperspb.Int32Value
		if limitNumber != 0 {
			limit = &wrapperspb.Int32Value{Value: int32(limitNumber)}
			limit = &wrapperspb.Int32Value{Value: limitNumber}
		}

		cursor := ""
		if f.Argument(3) != goja.Undefined() {
		if f.Argument(3) != goja.Undefined() && f.Argument(3) != goja.Null() {
			cursor = getJsString(r, f.Argument(3))
		}

		overrideExpiry := int64(0)
		if f.Argument(4) != goja.Undefined() {
		if f.Argument(4) != goja.Undefined() && f.Argument(4) != goja.Null() {
			overrideExpiry = getJsInt(r, f.Argument(4))
		}

@@ -4307,7 +4311,12 @@ func (n *runtimeJavascriptNakamaModule) leaderboardsGetId(r *goja.Runtime) func(

func (n *runtimeJavascriptNakamaModule) purchaseValidateApple(r *goja.Runtime) func(goja.FunctionCall) goja.Value {
	return func(f goja.FunctionCall) goja.Value {
		if n.config.GetIAP().Apple.SharedPassword == "" {
		password := n.config.GetIAP().Apple.SharedPassword
		if f.Argument(2) != goja.Undefined() {
			password = getJsString(r, f.Argument(2))
		}

		if password == "" {
			panic(r.NewGoError(errors.New("Apple IAP is not configured.")))
		}

@@ -4325,7 +4334,7 @@ func (n *runtimeJavascriptNakamaModule) purchaseValidateApple(r *goja.Runtime) f
			panic(r.NewTypeError("expects receipt"))
		}

		validation, err := ValidatePurchasesApple(context.Background(), n.logger, n.db, uid, n.config.GetIAP().Apple.SharedPassword, receipt)
		validation, err := ValidatePurchasesApple(context.Background(), n.logger, n.db, uid, password, receipt)
		if err != nil {
			panic(r.NewGoError(fmt.Errorf("error validating Apple receipt: %s", err.Error())))
		}
@@ -4775,7 +4784,7 @@ func leaderboardRecordsToJs(r *goja.Runtime, records []*api.LeaderboardRecord, o
		}
		recordMap["score"] = record.Score
		recordMap["subscore"] = record.Subscore
		recordMap["numScoore"] = record.NumScore
		recordMap["numScore"] = record.NumScore
		metadataMap := make(map[string]interface{})
		err := json.Unmarshal([]byte(record.Metadata), &metadataMap)
		if err != nil {
+3 −2
Changes for server/runtime_lua_nakama.go: 3 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -5802,7 +5802,8 @@ func leaderboardToLuaTable(l *lua.LState, leaderboard *api.Leaderboard) (*lua.LT
}

func (n *RuntimeLuaNakamaModule) purchaseValidateApple(l *lua.LState) int {
	if n.config.GetIAP().Apple.SharedPassword == "" {
	password := l.OptString(3, n.config.GetIAP().Apple.SharedPassword)
	if password == "" {
		l.RaiseError("Apple IAP is not configured.")
		return 0
	}
@@ -5824,7 +5825,7 @@ func (n *RuntimeLuaNakamaModule) purchaseValidateApple(l *lua.LState) int {
		return 0
	}

	validation, err := ValidatePurchasesApple(l.Context(), n.logger, n.db, userID, n.config.GetIAP().Apple.SharedPassword, receipt)
	validation, err := ValidatePurchasesApple(l.Context(), n.logger, n.db, userID, password, receipt)
	if err != nil {
		l.RaiseError("error validating Apple receipt: %v", err.Error())
		return 0
Loading