Skip to content

Commit

Permalink
Add AuthByTelegramData method in plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
iamelevich committed Feb 24, 2023
1 parent 911a204 commit 0349f22
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 19 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [Overview](#overview)
* [Requirements](#requirements)
* [Installation](#installation)
* [Autofill fields](#autofill-fields)
* [Example](#example)
* [Usage](#usage)
* [Contributing](#contributing)
Expand All @@ -24,6 +25,15 @@ This plugin implements [Telegram WebApp Auth](https://core.telegram.org/bots/web
go get github.com/iamelevich/pocketbase-plugin-telegram-auth
```

### Autofill fields

- `name` - string
- `first_name` - string
- `last_name` - string
- `telegram_username` - string
- `telegram_id` - string
- `language_code` - string

### Example

You can check examples in [examples folder](/examples)
Expand Down
2 changes: 1 addition & 1 deletion examples/webapp-react/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func main() {

// Setup tg auth for users collection
tgAuthPlugin.MustRegister(app, &tgAuthPlugin.Options{
BotToken: "6086153355:AAHQR0dRvmboEIfbsPT93GHczOnT355gmUE", // Better to use ENV variable for that
BotToken: "YOUR_SUPER_SECRET_BOT_TOKEN", // Better to use ENV variable for that
CollectionKey: "users",
})

Expand Down
39 changes: 37 additions & 2 deletions forms/record_telegram_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,47 @@ func (form *RecordTelegramLogin) Submit(
return nil, nil, err
}

authUser, err := form.GetAuthUserFromData()
if err != nil {
if authUser, err := form.GetAuthUserFromData(); err != nil {
return nil, nil, err
} else {
return form.submitWithAuthUser(authUser, beforeCreateFuncs...)
}
}

func (form *RecordTelegramLogin) SubmitWithTelegramData(
tgData *TelegramData, beforeCreateFuncs ...func(createForm *pbForms.RecordUpsert, authRecord *models.Record, authUser *auth.AuthUser) error,
) (*models.Record, *auth.AuthUser, error) {
authUser := auth.AuthUser{}

authUser.RawUser = map[string]any{
"id": tgData.Id,
"first_name": tgData.FirstName,
"last_name": tgData.LastName,
"username": tgData.Username,
"language_code": tgData.LanguageCode,
"photo_url": tgData.PhotoUrl,
}

authUser.Id = strconv.FormatInt(tgData.Id, 10)
authUser.Username = tgData.Username
authUser.Name = strings.TrimSpace(tgData.FirstName + " " + tgData.LastName)
authUser.AvatarUrl = tgData.PhotoUrl

form.CreateData["name"] = authUser.Name
form.CreateData["first_name"] = tgData.FirstName
form.CreateData["last_name"] = tgData.LastName
form.CreateData["telegram_username"] = authUser.Username
form.CreateData["telegram_id"] = authUser.Id
form.CreateData["language_code"] = tgData.LanguageCode

return form.submitWithAuthUser(&authUser, beforeCreateFuncs...)
}

func (form *RecordTelegramLogin) submitWithAuthUser(
authUser *auth.AuthUser, beforeCreateFuncs ...func(createForm *pbForms.RecordUpsert, authRecord *models.Record, authUser *auth.AuthUser) error,
) (*models.Record, *auth.AuthUser, error) {
var authRecord *models.Record
var err error

// check for existing relation with the auth record
rel, _ := form.dao.FindExternalAuthByProvider("telegram", authUser.Id)
Expand Down
71 changes: 55 additions & 16 deletions plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ type Options struct {
CollectionKey string
}

type plugin struct {
app core.App
options *Options
type Plugin struct {
app core.App
options *Options
collection *models.Collection
}

func (p *plugin) Validate() error {
func (p *Plugin) Validate() error {
if p.options.BotToken == "" {
return fmt.Errorf("bot token is required")
}
Expand All @@ -41,14 +42,52 @@ func (p *plugin) Validate() error {
return nil
}

func MustRegister(app core.App, options *Options) {
if err := Register(app, options); err != nil {
func (p *Plugin) GetCollection() (*models.Collection, error) {
// If collection object stored in plugin - return it
if p.collection != nil {
return p.collection, nil
}

// If no collection object - find it, store and return
if collection, err := p.app.Dao().FindCollectionByNameOrId(p.options.CollectionKey); err != nil {
return nil, err
} else {
p.collection = collection
return collection, nil
}
}

func (p *Plugin) GetForm(optAuthRecord *models.Record) (*forms.RecordTelegramLogin, error) {
collection, findCollectionErr := p.GetCollection()
if findCollectionErr != nil {
return nil, findCollectionErr
}
if collection.Type != models.CollectionTypeAuth {
return nil, errors.New("Wrong collection type. " + p.options.CollectionKey + " should be auth collection")
}

return forms.NewRecordTelegramLogin(p.app, p.options.BotToken, collection, optAuthRecord), nil
}

func (p *Plugin) AuthByTelegramData(tgData forms.TelegramData) (*models.Record, *auth.AuthUser, error) {
form, err := p.GetForm(nil)
if err != nil {
return nil, nil, err
}

return form.SubmitWithTelegramData(&tgData)
}

func MustRegister(app core.App, options *Options) *Plugin {
if p, err := Register(app, options); err != nil {
panic(err)
} else {
return p
}
}

func Register(app core.App, options *Options) error {
p := &plugin{app: app}
func Register(app core.App, options *Options) (*Plugin, error) {
p := &Plugin{app: app}

// Set default options
if options != nil {
Expand All @@ -59,7 +98,7 @@ func Register(app core.App, options *Options) error {

// Validate options
if err := p.Validate(); err != nil {
return err
return p, err
}

app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
Expand All @@ -68,21 +107,21 @@ func Register(app core.App, options *Options) error {
Method: http.MethodPost,
Path: "/api/collections/" + p.options.CollectionKey + "/auth-with-telegram",
Handler: func(c echo.Context) error {
collection, findCollectionErr := p.app.Dao().FindCollectionByNameOrId(p.options.CollectionKey)
collection, findCollectionErr := p.GetCollection()
if findCollectionErr != nil {
return findCollectionErr
}
if collection.Type != models.CollectionTypeAuth {
return errors.New("Wrong collection type. " + p.options.CollectionKey + " should be auth collection")
}
var fallbackAuthRecord *models.Record

var fallbackAuthRecord *models.Record
loggedAuthRecord, _ := c.Get(apis.ContextAuthRecordKey).(*models.Record)
if loggedAuthRecord != nil && loggedAuthRecord.Collection().Id == collection.Id {
fallbackAuthRecord = loggedAuthRecord
}

form := forms.NewRecordTelegramLogin(p.app, p.options.BotToken, collection, fallbackAuthRecord)
form, getFormErr := p.GetForm(fallbackAuthRecord)
if getFormErr != nil {
return getFormErr
}
if readErr := c.Bind(form); readErr != nil {
return apis.NewBadRequestError("An error occurred while loading the submitted data.", readErr)
}
Expand Down Expand Up @@ -138,5 +177,5 @@ func Register(app core.App, options *Options) error {
return routeError
})

return nil
return p, nil
}

0 comments on commit 0349f22

Please sign in to comment.