Giter Club home page Giter Club logo

supertokens-golang's Introduction

SuperTokens banner

SuperTokens Golang sdk

chat on Discord

About

This is a Golang library that is used to interface between a Go API process and the SuperTokens http service.

Learn more at https://supertokens.io

Documentation

To see documentation, please click here.

Contributing

Please see the CONTRIBUTING.md file for instructions.

Contact us

For any queries, or support requests, please email us at [email protected], or join our Discord server.

Authors

Created with ❤️ by the folks at SuperTokens.io.

supertokens-golang's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

supertokens-golang's Issues

Facebook login is not working with the backend crash

Stack trace:

net/http.(*conn).serve.func1()
        /usr/local/go/src/net/http/server.go:1825 +0xb0
panic({0x10299da40, 0x140001ec8a0})
        /usr/local/go/src/runtime/panic.go:844 +0x258
github.com/supertokens/supertokens-golang/recipe/thirdparty/providers.Facebook.func1.1({0x102997f00?, 0x14000115590?}, 0x140002068d0?)
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/providers/facebook.go:82 +0x25c
github.com/supertokens/supertokens-golang/recipe/thirdparty/api.MakeAPIImplementation.func2({{_, _}, _, _}, {_, _}, {_, _}, {_, _}, ...)
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/api/implementation.go:134 +0x3fc
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword/api.MakeAPIImplementation.func6({{_, _}, _, _}, {_, _}, {_, _}, {_, _}, ...)
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/api/implementation.go:106 +0x64
main.main.func1.1({{_, _}, _, _}, {_, _}, {_, _}, {_, _}, ...)
        /Users/sattvik/projects/supertokens/demo/thirdparty/backend/golang/main.go:65 +0x64
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword/api.GetThirdPartyIterfaceImpl.func1({{_, _}, _, _}, {_, _}, {_, _}, {_, _}, ...)
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/api/thirdPartyAPIImplementation.go:35 +0x68
github.com/supertokens/supertokens-golang/recipe/thirdparty/api.SignInUpAPI({_, _, _}, {{0x140000ae350, 0x140000ae358, 0x140000ae340, 0x140000ae348}, {0x140000ae230, 0x140000ae238, 0x140000ae240, ...}, ...})
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/api/signinup.go:81 +0x2bc
github.com/supertokens/supertokens-golang/recipe/thirdparty.(*Recipe).handleAPIRequest(0x6?, {0x1028cc46b?, 0xe?}, 0x69732f687475612f?, {0x129bfc1c0?, 0x1400020c258?}, 0x6e656e656b6f74?, {{0x140002081d2?, 0x1400020af20?}}, {0x14000208180?, ...})
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/recipe.go:144 +0x1ac
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword.(*Recipe).handleAPIRequest(0x140000d8b00, {0x1028cc46b, 0x9}, 0x1400020c270?, {0x129bfc1c0, 0x1400020c258}, 0x14000242418?, {{0x140002081d2?, 0x1029a7ce0?}}, {0x14000208180, ...})
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/recipe.go:191 +0x11c
github.com/supertokens/supertokens-golang/supertokens.(*superTokens).middleware.func2({0x1029f3498?, 0x1400024c0e0}, 0x1400022e400)
        /Users/sattvik/.go/pkg/mod/github.com/supertokens/[email protected]/supertokens/supertokens.go:229 +0x880
net/http.HandlerFunc.ServeHTTP(0x1029c9080?, {0x1029f3498?, 0x1400024c0e0?}, 0x20?)
        /usr/local/go/src/net/http/server.go:2084 +0x3c
main.corsMiddleware.func1({0x1029f3498, 0x1400024c0e0}, 0x1400022e400)
        /Users/sattvik/projects/supertokens/demo/thirdparty/backend/golang/main.go:154 +0x42c
net/http.HandlerFunc.ServeHTTP(0x0?, {0x1029f3498?, 0x1400024c0e0?}, 0x1026656d0?)
        /usr/local/go/src/net/http/server.go:2084 +0x3c
net/http.serverHandler.ServeHTTP({0x1029f26b0?}, {0x1029f3498, 0x1400024c0e0}, 0x1400022e400)
        /usr/local/go/src/net/http/server.go:2916 +0x3fc
net/http.(*conn).serve(0x140002361e0, {0x1029f36f0, 0x1400009bce0})
        /usr/local/go/src/net/http/server.go:1966 +0x56c
created by net/http.(*Server).Serve
        /usr/local/go/src/net/http/server.go:3071 +0x450

Typo at query param to core

Hey guys,
Thanks for the great work!
We are trying to integrate passwordless recipe with out existing users system.
But while using the passwordless.ListCodesByPreAuthSessionID(preAuthSessionID) method to retrieve the phone number of the current user we get 400 code from the core.
After looking at the sources I think that the problem is in:
github.com/supertokens/[email protected]/recipe/passwordless/recipeimplementation.go#235

		response, err := querier.SendGetRequest("/recipe/signinup/codes", map[string]string{
			"preAuthSessionID": preAuthSessionID,
		})

preAuthSessionID should be preAuthSessionId

Sign in with reddit yields 429 error

I have created a branch in the supertokens-golang repo: https://github.com/supertokens/supertokens-golang/tree/sign-in-with-reddit which contains an example app with sign in with reddit that yields a 429 error.

To run the app, do:

cd supertokens-golang/examples/with-http
go run main.go

You will need to setup your frontend react app to use thirdpartyemailpassword recipe and add this provider in the providers list.:

{
   id: "reddit",
   name: "Reddit"
}

If you do not have a frontend app setup, you can use this example app. Before running npm run start though, make sure to comment out this line (it will disable the node server in the example app to listen on port 3001 since we are running the backend via the go with-http example above.

Then on the frontend, you can click on "Sign in with reddit" and post redirection, you should see the following output in your terminal (where you ran the go command):

Status code:
429
invalid character '<' looking for beginning of value

This indicates that reddit returned a 429 status code (too many requests). This happens when calling the https://www.reddit.com/api/v1/access_token API to exchange the auth code with the access token.

The API call in the SDK that yields this error happens here. When trying to fix this issue, feel free to modify this file and rerun the signin process via the frontend app.

Enable Custom HTTP client for communication with supertokens core

Environments like google cloud run require authentication for private service to service communication. This is currently difficult to accommodate between the sdk and supertokens core since there are no direct means of changing that client behavior.

Enabling some customization would help deployments in cloud run as well as other similar environments.

Workarounds include

  • Making the supertokens core endpoint public
  • Doing some network indirection using serverless vpc access and a load balancer
  • Using runsd to proxy outbound requests and add the necessary headers

GoFiber Example Crashes

What

Checkout the newest changes from #198 and make an unauthenticated call. The VerifySession Function will not catch it as an error and will call ctx.next() ALTHOUGH the session is unauthenticated, leading to a Nil pointer reference if you try to fetch the user session or user data later on.

Why

Your new "fixed" implementation looks like this

err = adaptor.HTTPHandlerFunc(session.VerifySession(options, func(rw http.ResponseWriter, r *http.Request) {
	c.SetUserContext(r.Context())
}))(c)
if err != nil {
	return ...
}

but if you look at the implementation of adaptor.HTTPHandlerFunc then you'll see that it is implemented like this

return func(c *fiber.Ctx) error {
	handler := fasthttpadaptor.NewFastHTTPHandler(h)
	handler(c.Context())
	return nil
}

meaning it will always return nil, no matter the outcome of session.VerifySession

Go try it for yourself

Figure out a better way to do input normalisation

Right now, we have to pass the recipe instance to the verifyAndNormaliseInput function for each recipe - while the recipe instance has not been fully initialised yet. This means that if the verifyAndNormaliseInput function uses any of the non initialised fields, it will cause an issue.

Improper usage of keyfunc leading to leaking goroutines and compounding scheduled HTTP requests

Currently there are two functions that use the github.com/MicahParks/keyfunc package.

  1. Apple related function
  2. Google Workspaces related function

They both share this snippet of code:

// Create the keyfunc options. Refresh the JWKS every hour and log errors.
refreshInterval := time.Hour
options := keyfunc.Options{
  RefreshInterval: refreshInterval,
}

// Create the JWKS from the resource at the given URL.
jwks, err := keyfunc.Get(jwksURL, options)
if err != nil {
  return claims, err
}

// Parse the JWT.
token, err := jwt.ParseWithClaims(idToken, claims, jwks.Keyfunc)
if err != nil {
  return claims, err
}

When using the RefreshInterval field in the keyfunc.Options data structure, a background goroutine will be launched to refresh the JWKS at the given interval. Additionally, there is a comment that suggests errors from the keyfunc's background goroutine will be logged, however, the RefreshErrorHandler field was not specified, so this is not the case. Reference.

Since the function creates a new *keyfunc.JWKS via keyfunc.Get every time it is called and it does not end the background goroutine for the *keyfunc.JWKS, these two functions leak goroutines every time they are called. This can be problematic because it is a resource leak and each of these leaked goroutines will make an HTTP request to their JWKS endpoints at the given interval, forever.

As a note, a *keyfunc.JWKS's background goroutine can be ended via the EndBackground method or via the context given by the keyfunc.Options to the keyfunc.Get function.

I suggest doing one of the two things:

  1. Pass an empty keyfunc.Options to the keyfunc.Get function. This will keep the current behavior, but no background goroutine will be launched.
  2. Move the creation of the *keyfunc.JWKS outside of these functions. (The creation of this data structure is the result of a call to the keyfunc.Get function.) This would allow the same *keyfunc.JWKS to be reused across function calls. If you chose this option, I would also suggest exposing a way for the users of the supertokens-golang package to end any background goroutines.

Example on how to use supertokens with go-zero

https://github.com/zeromicro/go-zero

I tried to initialize supertokens in go-zero but getting 404. only /sessioninfo endpoint seems to work properly. Here is the code.

package main

import (
	"backbone/service/gateway/api/internal/config"
	"backbone/service/gateway/api/internal/handler"
	"backbone/service/gateway/api/internal/svc"
	"encoding/json"
	"net/http"
	"strings"

	"github.com/supertokens/supertokens-golang/recipe/passwordless"
	"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/supertokens"

	"flag"
	"fmt"

	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/rest"
)

var configFile = flag.String("f", "etc/gateway.yaml", "the config file")

func main() {
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)

	server := rest.MustNewServer(c.RestConf)
	defer server.Stop()

	// supertokens
	err := supertokens.Init(supertokens.TypeInput{
		Supertokens: &supertokens.ConnectionInfo{
			//These are the connection details of the app you created on supertokens.com
			ConnectionURI: c.Supertokens.ConnectionURI,
			APIKey:        c.Supertokens.APIKey,
		},
		AppInfo: supertokens.AppInfo{
			AppName:         c.Supertokens.AppName,
			APIDomain:       c.Supertokens.APIDomain,
			WebsiteDomain:   c.Supertokens.WebsiteDomain,
			APIBasePath:     &c.Supertokens.APIBasePath,
			WebsiteBasePath: &c.Supertokens.WebsiteBasePath,
		},
		RecipeList: []supertokens.Recipe{
			passwordless.Init(plessmodels.TypeInput{
				FlowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
				ContactMethodEmailOrPhone: plessmodels.ContactMethodEmailOrPhoneConfig{
					Enabled: true,
				},
			}),
			session.Init(nil), // initializes session features
		},
	})
	if err != nil {
		panic(err.Error())
	}

	server.Use(corsMiddleware)
	server.Use(rest.ToMiddleware(supertokens.Middleware))
	server.AddRoute(rest.Route{
		Method: http.MethodGet,
		Path:   "/sessioninfo",
		Handler: func(rw http.ResponseWriter, r *http.Request) {
			session.VerifySession(nil, sessioninfo).ServeHTTP(rw, r)
		},
	})

	ctx := svc.NewServiceContext(c)
	handler.RegisterHandlers(server, ctx)

	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
	server.Start()
}

func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(response http.ResponseWriter, r *http.Request) {
		var c config.Config
		conf.MustLoad(*configFile, &c)

		response.Header().Set("Access-Control-Allow-Origin", c.Supertokens.WebsiteDomain)
		response.Header().Set("Access-Control-Allow-Credentials", "true")
		if r.Method == "OPTIONS" {
			response.Header().Set("Access-Control-Allow-Headers", strings.Join(append([]string{"Content-Type"}, supertokens.GetAllCORSHeaders()...), ","))
			response.Header().Set("Access-Control-Allow-Methods", "*")
			response.Write([]byte(""))
		} else {
			next.ServeHTTP(response, r)
		}
	}
}

func sessioninfo(w http.ResponseWriter, r *http.Request) {
	sessionContainer := session.GetSessionFromRequestContext(r.Context())

	if sessionContainer == nil {
		w.WriteHeader(500)
		w.Write([]byte("no session found"))
		return
	}
	sessionData, err := sessionContainer.GetSessionData()
	if err != nil {
		err = supertokens.ErrorHandler(err, r, w)
		if err != nil {
			w.WriteHeader(500)
			w.Write([]byte(err.Error()))
		}
		return
	}
	w.WriteHeader(200)
	w.Header().Add("content-type", "application/json")
	bytes, err := json.Marshal(map[string]interface{}{
		"sessionHandle":      sessionContainer.GetHandle(),
		"userId":             sessionContainer.GetUserID(),
		"accessTokenPayload": sessionContainer.GetAccessTokenPayload(),
		"sessionData":        sessionData,
	})
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte("error in converting to json"))
	} else {
		w.Write(bytes)
	}
}

GoLang SDK release

Create and release the golang SDK

TODO:

  • Create golang ID on the backend and remove go ID
  • Make the go repo deprecated and link it to golang repo
  • Push docs to production
  • Build supertokens-website server
  • Build supertokens-auth-react server
  • Setup CICD for repo
  • Check if we have blocking release of core if golang is not updated with new CDI in future?
  • Put it on the main golang distribution site
  • Check if telemetry is working or not
  • Check why handshake info and verifySession is being called so many times.
  • UTF-8 compatibility for JWT decoding

Need for locking?

  • Since go is multi threaded, we might have to lock around resource access like when accessing the handshake info

Does session.GetSessionFromRequestContext support grpc request ?

I have written a simple grpc server to authenticate user requests, but currently the value obtained by "session.GetSessionFromRequestContext" is empty, does it support grpc requests? Or am I using it in the wrong way?

I used postman to request the local grpc service, and the cookie: value was placed in the metadata, and there is information about it in the logs.

image

The server code:

package grpc

import (
	corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
	authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
	typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
	log "github.com/sirupsen/logrus"
	session "github.com/supertokens/supertokens-golang/recipe/session"
	"golang.org/x/net/context"
	"google.golang.org/genproto/googleapis/rpc/status"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/reflection"
	"net"
)

const (
	xUserId         = "x-cos-user-id"
	xOrganizationId = "x-cos-organization-id"
)

type (
	extAuthzServerV3 struct{}
)

type ExtAuthzServer struct {
	grpcServer *grpc.Server
	grpcV3     *extAuthzServerV3
}

func Init() {
	s := NewExtAuthzServer()
	s.startGRPC()
}

func NewExtAuthzServer() *ExtAuthzServer {
	return &ExtAuthzServer{
		grpcV3: &extAuthzServerV3{},
	}
}

func (s *ExtAuthzServer) startGRPC() {
	listener, err := net.Listen("tcp", ":6565")
	if err != nil {
		log.Fatalf("Failed to start gRPC server: %v", err)
		return
	}

	s.grpcServer = grpc.NewServer()

	reflection.Register(s.grpcServer)
	authv3.RegisterAuthorizationServer(s.grpcServer, s.grpcV3)

	log.Printf("Starting gRPC server at %s", listener.Addr())
	if err := s.grpcServer.Serve(listener); err != nil {
		log.Fatalf("Failed to serve gRPC server: %v", err)
		return
	}
}

// Check implements gRPC v3 check request.
func (s *extAuthzServerV3) Check(ctx context.Context, request *authv3.CheckRequest) (*authv3.CheckResponse, error) {
	sessionContainer := session.GetSessionFromRequestContext(ctx)
	log.Infof("sessionContainer is nil: %v", sessionContainer == nil)

	md, ok := metadata.FromIncomingContext(ctx)
	log.Infof("metadata: %v, ok: %v", md, ok)

	log.Infof("request attrs: %v", request.GetAttributes())

	return s.deny(request), nil
}

func (s *extAuthzServerV3) allow(request *authv3.CheckRequest) *authv3.CheckResponse {
	return &authv3.CheckResponse{
		HttpResponse: &authv3.CheckResponse_OkResponse{
			OkResponse: &authv3.OkHttpResponse{
				Headers: []*corev3.HeaderValueOption{
					{
						Header: &corev3.HeaderValue{
							Key:   "x-cos-user-id",
							Value: "hello",
						},
					},
					{
						Header: &corev3.HeaderValue{
							Key:   "x-cos-organization-id",
							Value: request.GetAttributes().String(),
						},
					},
				},
			},
		},
		Status: &status.Status{Code: int32(codes.OK)},
	}
}

func (s *extAuthzServerV3) deny(request *authv3.CheckRequest) *authv3.CheckResponse {
	return &authv3.CheckResponse{
		HttpResponse: &authv3.CheckResponse_DeniedResponse{
			DeniedResponse: &authv3.DeniedHttpResponse{
				Status: &typev3.HttpStatus{Code: typev3.StatusCode_Forbidden},
				Body:   "deny request",
				Headers: []*corev3.HeaderValueOption{
					{
						Header: &corev3.HeaderValue{
							Key:   xUserId,
							Value: "",
						},
					},
					{
						Header: &corev3.HeaderValue{
							Key:   xOrganizationId,
							Value: "",
						},
					},
				},
			},
		},
		Status: &status.Status{Code: int32(codes.PermissionDenied)},
	}
}

Server Panic on invalid or already verified third party code.

Hey, yesterday I started connecting my custom frontend with the backend.

I'm using the following SuperTokens packages:

  • supertokens-auth-react (v0.22.0)
  • supertokens-golang (v0.6.6)

For the backend I also use gofiber (v2.34.1).
When I implemented the frontend I was first implementing the thirdPartySignInAndUp() without the react useEffect hook which resulted in at least three api calls to my backend.

It appears that sometimes the code wasn't present at all or already verified which caused the following server panic:

panic: interface conversion: interface {} is nil, not string

goroutine 33 [running]:
github.com/supertokens/supertokens-golang/recipe/thirdparty/providers.Facebook.func1.1({0xbb0a40?, 0xc000022780?}, 0x32?)
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/providers/facebook.go:82 +0x265
github.com/supertokens/supertokens-golang/recipe/thirdparty/api.MakeAPIImplementation.func2({{_, _}, _, _}, {_, _}, {_, _}, {0xc000287680, 0x2c}, ...)
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/api/implementation.go:134 +0x51e
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword/api.MakeAPIImplementation.func6({{_, _}, _, _}, {_, _}, {_, _}, {0xc000287680, 0x2c}, ...)
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/api/implementation.go:106 +0xa3
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword/api.GetThirdPartyIterfaceImpl.func1({{_, _}, _, _}, {_, _}, {_, _}, {0xc000287680, 0x2c}, ...)
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/api/thirdPartyAPIImplementation.go:35 +0xa4
github.com/supertokens/supertokens-golang/recipe/thirdparty/api.SignInUpAPI({_, _, _}, {{0xc0000ce480, 0xc0000ce488, 0xc0000ce470, 0xc0000ce478}, {0xc0000ce360, 0xc0000ce368, 0xc0000ce370, ...}, ...})
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/api/signinup.go:80 +0x383
github.com/supertokens/supertokens-golang/recipe/thirdparty.(*Recipe).handleAPIRequest(0x69732f687475612f?, {0xc13855?, 0x2f7966697265762f?}, 0x6e656e656b6f74?, {0x160ae2700e0?, 0xc000097590?}, 0xc0000fba20?, {{0xc0000a9db2?, 0xc000298640?}}, {0xc000280ac0, ...})
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdparty/recipe.go:144 +0x29b
github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword.(*Recipe).handleAPIRequest(0xc0000e8b00, {0xc13855, 0x9}, 0xc17072?, {0x160ae2700e0, 0xc000097590}, 0xbc0cc0?, {{0xc0000a9db2?, 0x0?}}, {0xc000280ac0, ...})
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/recipe/thirdpartyemailpassword/recipe.go:191 +0x1aa
github.com/supertokens/supertokens-golang/supertokens.(*superTokens).middleware.func2({0xcc7a10?, 0xc000295530}, 0xc00017eb00)
        C:/Users/flixoflax/go/pkg/mod/github.com/supertokens/[email protected]/supertokens/supertokens.go:225 +0xb4b
net/http.HandlerFunc.ServeHTTP(0xc000308000?, {0xcc7a10?, 0xc000295530?}, 0xcb?)
        C:/Program Files/Go/src/net/http/server.go:2084 +0x2f
github.com/valyala/fasthttp/fasthttpadaptor.NewFastHTTPHandler.func1(0xc000308000)
        C:/Users/flixoflax/go/pkg/mod/github.com/valyala/[email protected]/fasthttpadaptor/adaptor.go:57 +0x287
github.com/gofiber/adaptor/v2.HTTPHandler.func1(0xc0000e98c0)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/adaptor/[email protected]/main.go:27 +0x43
github.com/gofiber/adaptor/v2.HTTPMiddleware.func1(0xc0000e98c0)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/adaptor/[email protected]/main.go:48 +0xb2
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc000308318?)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:799 +0x43
github.com/gofiber/fiber/v2/middleware/cors.New.func1(0xc0000e98c0)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/fiber/[email protected]/middleware/cors/cors.go:141 +0x292
github.com/gofiber/fiber/v2.(*App).next(0xc0000001e0, 0xc0000e98c0)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:132 +0x1be
github.com/gofiber/fiber/v2.(*App).handler(0xc0000001e0, 0x8bf397?)
        C:/Users/flixoflax/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:159 +0x45
github.com/valyala/fasthttp.(*Server).serveConn(0xc000066000, {0xcc87f8?, 0xc0000ce6f0})
        C:/Users/flixoflax/go/pkg/mod/github.com/valyala/[email protected]/server.go:2338 +0x1268
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000056280, 0xc0001dd600)
        C:/Users/flixoflax/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:224 +0xa9
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
        C:/Users/flixoflax/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:196 +0x38
created by github.com/valyala/fasthttp.(*workerPool).getCh
        C:/Users/flixoflax/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x1b0
exit status 2

This first line could mean that somewhere in the supertokens-golang sdk a conversion happens unsafe.
For any questions regarding my implementation feel free to contact me :D

GoFiber Example: GoFiber ErrorHandler not called

What

Imagine having a normal GoFiber Instance setup like this with a custom ErrorHandler just to add some custom error formatters. I think thats not a rare case.

app := fiber.New(fiber.Config{
	ErrorHandler: func (ctx *fiber.Ctx, err error) error { return err },
})

Then with the current implementation of an auth middleware like its currently shown in the example, the goFiber error handler is never called, because all the response writing already happened in the callback of the session.verifySession function on the net/http instance of the request

func verifySession(options *sessmodels.VerifySessionOptions) fiber.Handler {
return func(c *fiber.Ctx) error {
return adaptor.HTTPHandlerFunc(http.HandlerFunc(session.VerifySession(options, func(rw http.ResponseWriter, r *http.Request) {
c.SetUserContext(r.Context())
err := c.Next()
if err != nil {
err = supertokens.ErrorHandler(err, r, rw)
if err != nil {
rw.WriteHeader(500)
_, _ = rw.Write([]byte(err.Error()))
}
return
}
c.Response().Header.VisitAll(func(k, v []byte) {
if string(k) == fasthttp.HeaderContentType {
rw.Header().Set(string(k), string(v))
}
})
rw.WriteHeader(c.Response().StatusCode())
_, _ = rw.Write(c.Response().Body())
})))(c)
}
}

(PR incoming to fix this)

Overrides doesn't work if not overriden inplace

For example

session.Init(&sessmodels.TypeInput{
	AntiCsrf: &customAntiCsrfVal,
	Override: &sessmodels.OverrideStruct{
		Functions: func(originalImplementation sessmodels.RecipeInterface) sessmodels.RecipeInterface {
			oGetSessionInformation := *originalImplementation.GetSessionInformation
			nGetSessionInformation := func(sessionHandle string, userContext supertokens.UserContext) (*sessmodels.SessionInformation, error) {
				info, err := oGetSessionInformation(sessionHandle, userContext)
				if err != nil {
					return nil, err
				}
				info.SessionData = map[string]interface{}{
					"test": 1,
				}
				return info, nil
			}
			originalImplementation.GetSessionInformation = &nGetSessionInformation
			return originalImplementation
		},
	},
})

Empty reponse in API override with custom response causes panic

For example:

originalCreateCodePOST := *originalImplementation.CreateCodePOST
(*originalImplementation.CreateCodePOST) = func(email *string, phoneNumber *string, optionsCreateCode plessmodels.APIOptions, userContextCreateCode supertokens.UserContext) (plessmodels.CreateCodePOSTResponse, error) {
  err := validatePhone(*phoneNumber)
  if err != nil {
    responseJson := map[string]interface{}{
      "message": err.Error(),
    }

    bytes, _ := json.Marshal(responseJson)

    optionsCreateCode.Res.Header().Set("Content-Type", "application/json")
    optionsCreateCode.Res.WriteHeader(400)
    optionsCreateCode.Res.Write(bytes)

    return plessmodels.CreateCodePOSTResponse{}, nil
  }
  return originalCreateCodePOST(email, phoneNumber, optionsCreateCode, userContextCreateCode)
}
return originalImplementation

panics inside createCode.go

if response.OK != nil {
    result = map[string]interface{}{
	    "status":           "OK",
	    "deviceId":         response.OK.DeviceID,
	    "preAuthSessionId": response.OK.PreAuthSessionID,
	    "flowType":         response.OK.FlowType,
    }
} else {
    result = map[string]interface{}{
	    "status":  "GENERAL_ERROR",
	    "message": response.GeneralError.Message,
    }
}

trying to access Message inside nil (response.GeneralError)

Add new func for manual check accessToken

#158

The current GetSession binds http and cookies, and I hope to add a separate function that allows the user to check accessToken separately (the user may have gotten cookie-related information through other fields)

Request body is empty for POST Requests Golang

Request body of Signup POST API is empty after calling original implementation.

Use case: To pass and use additional key value pairs from the request body of Signup POST API

						// First we copy the original implementation
						originalThirdPartySignInUpPOST := *originalImplementation.ThirdPartySignInUpPOST

						// we override the thirdpartyemailpassword signinup POST API to return the social provider's access token
						(*originalImplementation.ThirdPartySignInUpPOST) = func(provider tpmodels.TypeProvider, code string, authCodeResponse interface{}, redirectURI string, options tpmodels.APIOptions, userContext supertokens.UserContext) (tpepmodels.ThirdPartyOutput, error) {

							body := options.Req.Body

							strBody, err := ioutil.ReadAll(body)
							if err != nil {
								fmt.Println("err in printing body", err)
							}
							fmt.Printf("strBody??? %s", strBody)```

optimalization: redundant loops

I don't see the reason for why two separate loops is needed to extract the values.
Why not have both if checks inside the same first loop?

var email string
for _, formField := range formFields {
if formField.ID == "email" {
email = formField.Value
}
}
var password string
for _, formField := range formFields {
if formField.ID == "password" {
password = formField.Value
}
}

ps: this happens in multiple places.

Add copyright to all src code files (can do as last step)

/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
 *
 * This software is licensed under the Apache License, Version 2.0 (the
 * "License") as published by the Apache Software Foundation.
 *
 * You may not use this file except in compliance with the License. You may
 * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

v.0.10.0 breaks session.VerifySession()

With v0.9.14 everything works as expected and I can login to my App. However when using v0.10.0 I get a 401 Status Code for any handler wrapped in session.VerifySession

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.