mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-04 23:40:10 +00:00
Telegram: Allow admin to add telegram contact
Works in the same way as on the form, but can now be done in the accounts tab.
This commit is contained in:
parent
0f41d1e6cf
commit
2d93b3b7ee
102
api.go
102
api.go
@ -490,6 +490,9 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
if lang, ok := app.telegram.languages[tgToken.ChatID]; ok {
|
if lang, ok := app.telegram.languages[tgToken.ChatID]; ok {
|
||||||
tgUser.Lang = lang
|
tgUser.Lang = lang
|
||||||
}
|
}
|
||||||
|
if app.storage.telegram == nil {
|
||||||
|
app.storage.telegram = map[string]TelegramUser{}
|
||||||
|
}
|
||||||
app.storage.telegram[user.ID] = tgUser
|
app.storage.telegram[user.ID] = tgUser
|
||||||
err := app.storage.storeTelegramUsers()
|
err := app.storage.storeTelegramUsers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1474,6 +1477,7 @@ func (app *appContext) ModifyConfig(gc *gin.Context) {
|
|||||||
// @Param lang query string false "Language for email titles."
|
// @Param lang query string false "Language for email titles."
|
||||||
// @Success 200 {object} emailListDTO
|
// @Success 200 {object} emailListDTO
|
||||||
// @Router /config/emails [get]
|
// @Router /config/emails [get]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) GetCustomEmails(gc *gin.Context) {
|
func (app *appContext) GetCustomEmails(gc *gin.Context) {
|
||||||
lang := gc.Query("lang")
|
lang := gc.Query("lang")
|
||||||
@ -1502,6 +1506,7 @@ func (app *appContext) GetCustomEmails(gc *gin.Context) {
|
|||||||
// @Failure 500 {object} boolResponse
|
// @Failure 500 {object} boolResponse
|
||||||
// @Param id path string true "ID of email"
|
// @Param id path string true "ID of email"
|
||||||
// @Router /config/emails/{id} [post]
|
// @Router /config/emails/{id} [post]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) SetCustomEmail(gc *gin.Context) {
|
func (app *appContext) SetCustomEmail(gc *gin.Context) {
|
||||||
var req customEmail
|
var req customEmail
|
||||||
@ -1561,6 +1566,7 @@ func (app *appContext) SetCustomEmail(gc *gin.Context) {
|
|||||||
// @Param enable/disable path string true "enable/disable"
|
// @Param enable/disable path string true "enable/disable"
|
||||||
// @Param id path string true "ID of email"
|
// @Param id path string true "ID of email"
|
||||||
// @Router /config/emails/{id}/state/{enable/disable} [post]
|
// @Router /config/emails/{id}/state/{enable/disable} [post]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) SetCustomEmailState(gc *gin.Context) {
|
func (app *appContext) SetCustomEmailState(gc *gin.Context) {
|
||||||
id := gc.Param("id")
|
id := gc.Param("id")
|
||||||
@ -1610,6 +1616,7 @@ func (app *appContext) SetCustomEmailState(gc *gin.Context) {
|
|||||||
// @Failure 500 {object} boolResponse
|
// @Failure 500 {object} boolResponse
|
||||||
// @Param id path string true "ID of email"
|
// @Param id path string true "ID of email"
|
||||||
// @Router /config/emails/{id} [get]
|
// @Router /config/emails/{id} [get]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
||||||
lang := app.storage.lang.chosenEmailLang
|
lang := app.storage.lang.chosenEmailLang
|
||||||
@ -1798,6 +1805,7 @@ func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} checkUpdateDTO
|
// @Success 200 {object} checkUpdateDTO
|
||||||
// @Router /config/update [get]
|
// @Router /config/update [get]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) CheckUpdate(gc *gin.Context) {
|
func (app *appContext) CheckUpdate(gc *gin.Context) {
|
||||||
if !app.newUpdate {
|
if !app.newUpdate {
|
||||||
@ -1812,6 +1820,7 @@ func (app *appContext) CheckUpdate(gc *gin.Context) {
|
|||||||
// @Success 400 {object} stringResponse
|
// @Success 400 {object} stringResponse
|
||||||
// @Success 500 {object} boolResponse
|
// @Success 500 {object} boolResponse
|
||||||
// @Router /config/update [post]
|
// @Router /config/update [post]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Configuration
|
// @tags Configuration
|
||||||
func (app *appContext) ApplyUpdate(gc *gin.Context) {
|
func (app *appContext) ApplyUpdate(gc *gin.Context) {
|
||||||
if !app.update.CanUpdate {
|
if !app.update.CanUpdate {
|
||||||
@ -1837,6 +1846,7 @@ func (app *appContext) ApplyUpdate(gc *gin.Context) {
|
|||||||
// @Success 200 {object} boolResponse
|
// @Success 200 {object} boolResponse
|
||||||
// @Failure 500 {object} stringResponse
|
// @Failure 500 {object} stringResponse
|
||||||
// @Router /logout [post]
|
// @Router /logout [post]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) Logout(gc *gin.Context) {
|
func (app *appContext) Logout(gc *gin.Context) {
|
||||||
cookie, err := gc.Cookie("refresh")
|
cookie, err := gc.Cookie("refresh")
|
||||||
@ -1910,7 +1920,94 @@ func (app *appContext) ServeLang(gc *gin.Context) {
|
|||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Returns true/false on whether or not a telegram PIN was verified.
|
// @Summary Returns a new Telegram verification PIN, and the bot username.
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} telegramPinDTO
|
||||||
|
// @Router /telegram/pin [get]
|
||||||
|
// @Security Bearer
|
||||||
|
// @tags Other
|
||||||
|
func (app *appContext) TelegramGetPin(gc *gin.Context) {
|
||||||
|
gc.JSON(200, telegramPinDTO{
|
||||||
|
Token: app.telegram.NewAuthToken(),
|
||||||
|
Username: app.telegram.username,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Link a Jellyfin & Telegram user together via a verification PIN.
|
||||||
|
// @Produce json
|
||||||
|
// @Param telegramSetDTO body telegramSetDTO true "Token and user's Jellyfin ID."
|
||||||
|
// @Success 200 {object} boolResponse
|
||||||
|
// @Failure 500 {object} boolResponse
|
||||||
|
// @Failure 400 {object} boolResponse
|
||||||
|
// @Router /users/telegram [post]
|
||||||
|
// @Security Bearer
|
||||||
|
// @tags Other
|
||||||
|
func (app *appContext) TelegramAddUser(gc *gin.Context) {
|
||||||
|
var req telegramSetDTO
|
||||||
|
gc.BindJSON(&req)
|
||||||
|
if req.Token == "" || req.ID == "" {
|
||||||
|
respondBool(400, false, gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tokenIndex := -1
|
||||||
|
for i, v := range app.telegram.verifiedTokens {
|
||||||
|
if v.Token == req.Token {
|
||||||
|
tokenIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tokenIndex == -1 {
|
||||||
|
respondBool(500, false, gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tgToken := app.telegram.verifiedTokens[tokenIndex]
|
||||||
|
tgUser := TelegramUser{
|
||||||
|
ChatID: tgToken.ChatID,
|
||||||
|
Username: tgToken.Username,
|
||||||
|
Contact: true,
|
||||||
|
}
|
||||||
|
if lang, ok := app.telegram.languages[tgToken.ChatID]; ok {
|
||||||
|
tgUser.Lang = lang
|
||||||
|
}
|
||||||
|
if app.storage.telegram == nil {
|
||||||
|
app.storage.telegram = map[string]TelegramUser{}
|
||||||
|
}
|
||||||
|
app.storage.telegram[req.ID] = tgUser
|
||||||
|
err := app.storage.storeTelegramUsers()
|
||||||
|
if err != nil {
|
||||||
|
app.err.Printf("Failed to store Telegram users: %v", err)
|
||||||
|
} else {
|
||||||
|
app.telegram.verifiedTokens[len(app.telegram.verifiedTokens)-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[len(app.telegram.verifiedTokens)-1]
|
||||||
|
app.telegram.verifiedTokens = app.telegram.verifiedTokens[:len(app.telegram.verifiedTokens)-1]
|
||||||
|
}
|
||||||
|
respondBool(200, true, gc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Returns true/false on whether or not a telegram PIN was verified. Requires bearer auth.
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} boolResponse
|
||||||
|
// @Param pin path string true "PIN code to check"
|
||||||
|
// @Router /telegram/verified/{pin} [get]
|
||||||
|
// @Security Bearer
|
||||||
|
// @tags Other
|
||||||
|
func (app *appContext) TelegramVerified(gc *gin.Context) {
|
||||||
|
pin := gc.Param("pin")
|
||||||
|
tokenIndex := -1
|
||||||
|
for i, v := range app.telegram.verifiedTokens {
|
||||||
|
if v.Token == pin {
|
||||||
|
tokenIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if tokenIndex != -1 {
|
||||||
|
// length := len(app.telegram.verifiedTokens)
|
||||||
|
// app.telegram.verifiedTokens[length-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[length-1]
|
||||||
|
// app.telegram.verifiedTokens = app.telegram.verifiedTokens[:length-1]
|
||||||
|
// }
|
||||||
|
respondBool(200, tokenIndex != -1, gc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Returns true/false on whether or not a telegram PIN was verified. Requires invite code.
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} boolResponse
|
// @Success 200 {object} boolResponse
|
||||||
// @Success 401 {object} boolResponse
|
// @Success 401 {object} boolResponse
|
||||||
@ -1918,7 +2015,7 @@ func (app *appContext) ServeLang(gc *gin.Context) {
|
|||||||
// @Param invCode path string true "invite Code"
|
// @Param invCode path string true "invite Code"
|
||||||
// @Router /invite/{invCode}/telegram/verified/{pin} [get]
|
// @Router /invite/{invCode}/telegram/verified/{pin} [get]
|
||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) TelegramVerified(gc *gin.Context) {
|
func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.invites[code]; !ok {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
@ -1942,6 +2039,7 @@ func (app *appContext) TelegramVerified(gc *gin.Context) {
|
|||||||
|
|
||||||
// @Summary Restarts the program. No response means success.
|
// @Summary Restarts the program. No response means success.
|
||||||
// @Router /restart [post]
|
// @Router /restart [post]
|
||||||
|
// @Security Bearer
|
||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) restart(gc *gin.Context) {
|
func (app *appContext) restart(gc *gin.Context) {
|
||||||
app.info.Println("Restarting...")
|
app.info.Println("Restarting...")
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chip.btn:hover:not([disabled]):not(.textarea),
|
||||||
|
.chip.btn:focus:not([disabled]):not(.textarea) {
|
||||||
|
filter: brightness(var(--button-filter-brightness,95%));
|
||||||
|
}
|
||||||
|
|
||||||
.banner {
|
.banner {
|
||||||
margin: calc(-1 * var(--spacing-4,1rem));
|
margin: calc(-1 * var(--spacing-4,1rem));
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,24 @@
|
|||||||
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
|
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ if .telegram_enabled }}
|
||||||
|
<div id="modal-telegram" class="modal">
|
||||||
|
<div class="modal-content card">
|
||||||
|
<span class="heading mb-1">{{ .strings.linkTelegram }}</span>
|
||||||
|
<p class="content mb-1">{{ .strings.sendPIN }}</p>
|
||||||
|
<h1 class="ac" id="telegram-pin"></h1>
|
||||||
|
<a class="subheading link-center" id="telegram-link" target="_blank">
|
||||||
|
<span class="shield ~info mr-1">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="ri-telegram-line"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
@<span id="telegram-username">
|
||||||
|
</a>
|
||||||
|
<span class="button ~info !normal full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
<div id="notification-box"></div>
|
<div id="notification-box"></div>
|
||||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||||
<span class="button ~urge dropdown-button">
|
<span class="button ~urge dropdown-button">
|
||||||
|
@ -92,7 +92,8 @@
|
|||||||
"inviteExpiresInTime": "Expires in {n}",
|
"inviteExpiresInTime": "Expires in {n}",
|
||||||
"notifyEvent": "Notify on:",
|
"notifyEvent": "Notify on:",
|
||||||
"notifyInviteExpiry": "On expiry",
|
"notifyInviteExpiry": "On expiry",
|
||||||
"notifyUserCreation": "On user creation"
|
"notifyUserCreation": "On user creation",
|
||||||
|
"sendPIN": "Ask the user to send the PIN below to the bot."
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"changedEmailAddress": "Changed email address of {n}.",
|
"changedEmailAddress": "Changed email address of {n}.",
|
||||||
@ -104,6 +105,7 @@
|
|||||||
"setOmbiDefaults": "Stored ombi defaults.",
|
"setOmbiDefaults": "Stored ombi defaults.",
|
||||||
"updateApplied": "Update applied, please restart.",
|
"updateApplied": "Update applied, please restart.",
|
||||||
"updateAppliedRefresh": "Update applied, please refresh.",
|
"updateAppliedRefresh": "Update applied, please refresh.",
|
||||||
|
"telegramVerified": "Telegram account verified.",
|
||||||
"errorConnection": "Couldn't connect to jfa-go.",
|
"errorConnection": "Couldn't connect to jfa-go.",
|
||||||
"error401Unauthorized": "Unauthorized. Try refreshing the page.",
|
"error401Unauthorized": "Unauthorized. Try refreshing the page.",
|
||||||
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
"copied": "Copied",
|
"copied": "Copied",
|
||||||
"time24h": "24h Time",
|
"time24h": "24h Time",
|
||||||
"time12h": "12h Time",
|
"time12h": "12h Time",
|
||||||
|
"linkTelegram": "Link Telegram",
|
||||||
|
"contactEmail": "Contact through Email",
|
||||||
|
"contactTelegram": "Contact through Telegram",
|
||||||
"theme": "Theme"
|
"theme": "Theme"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,7 @@
|
|||||||
"confirmationRequired": "Email confirmation required",
|
"confirmationRequired": "Email confirmation required",
|
||||||
"confirmationRequiredMessage": "Please check your email inbox to verify your address.",
|
"confirmationRequiredMessage": "Please check your email inbox to verify your address.",
|
||||||
"yourAccountIsValidUntil": "Your account will be valid until {date}.",
|
"yourAccountIsValidUntil": "Your account will be valid until {date}.",
|
||||||
"linkTelegram": "Link Telegram",
|
"sendPIN": "Send the PIN below to the bot, then come back here to link your account."
|
||||||
"sendPIN": "Send the PIN below to the bot, then come back here to link your account.",
|
|
||||||
"contactEmail": "Contact through Email",
|
|
||||||
"contactTelegram": "Contact through Telegram"
|
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"errorUserExists": "User already exists.",
|
"errorUserExists": "User already exists.",
|
||||||
|
10
models.go
10
models.go
@ -237,3 +237,13 @@ type checkUpdateDTO struct {
|
|||||||
New bool `json:"new"` // Whether or not there's a new update.
|
New bool `json:"new"` // Whether or not there's a new update.
|
||||||
Update Update `json:"update"`
|
Update Update `json:"update"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type telegramPinDTO struct {
|
||||||
|
Token string `json:"token" example:"A1-B2-3C"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type telegramSetDTO struct {
|
||||||
|
Token string `json:"token" example:"A1-B2-3C"`
|
||||||
|
ID string `json:"id"` // Jellyfin ID of user.
|
||||||
|
}
|
||||||
|
@ -119,7 +119,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
router.Use(static.Serve(p+"/invite/", app.webFS))
|
router.Use(static.Serve(p+"/invite/", app.webFS))
|
||||||
router.GET(p+"/invite/:invCode", app.InviteProxy)
|
router.GET(p+"/invite/:invCode", app.InviteProxy)
|
||||||
if app.config.Section("telegram").Key("enabled").MustBool(false) {
|
if app.config.Section("telegram").Key("enabled").MustBool(false) {
|
||||||
router.GET(p+"/invite/:invCode/telegram/verified/:pin", app.TelegramVerified)
|
router.GET(p+"/invite/:invCode/telegram/verified/:pin", app.TelegramVerifiedInvite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *SWAGGER {
|
if *SWAGGER {
|
||||||
@ -158,6 +158,11 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
api.GET(p+"/config", app.GetConfig)
|
api.GET(p+"/config", app.GetConfig)
|
||||||
api.POST(p+"/config", app.ModifyConfig)
|
api.POST(p+"/config", app.ModifyConfig)
|
||||||
api.POST(p+"/restart", app.restart)
|
api.POST(p+"/restart", app.restart)
|
||||||
|
if app.config.Section("telegram").Key("enabled").MustBool(false) {
|
||||||
|
api.GET(p+"/telegram/pin", app.TelegramGetPin)
|
||||||
|
api.GET(p+"/telegram/verified/:pin", app.TelegramVerified)
|
||||||
|
api.POST(p+"/users/telegram", app.TelegramAddUser)
|
||||||
|
}
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||||
api.GET(p+"/ombi/users", app.OmbiUsers)
|
api.GET(p+"/ombi/users", app.OmbiUsers)
|
||||||
api.POST(p+"/ombi/defaults", app.SetOmbiDefaults)
|
api.POST(p+"/ombi/defaults", app.SetOmbiDefaults)
|
||||||
|
@ -62,6 +62,10 @@ window.availableProfiles = window.availableProfiles || [];
|
|||||||
window.modals.extendExpiry = new Modal(document.getElementById("modal-extend-expiry"));
|
window.modals.extendExpiry = new Modal(document.getElementById("modal-extend-expiry"));
|
||||||
|
|
||||||
window.modals.updateInfo = new Modal(document.getElementById("modal-update"));
|
window.modals.updateInfo = new Modal(document.getElementById("modal-update"));
|
||||||
|
|
||||||
|
if (window.telegramEnabled) {
|
||||||
|
window.modals.telegram = new Modal(document.getElementById("modal-telegram"));
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
var inviteCreator = new createInvite();
|
var inviteCreator = new createInvite();
|
||||||
|
@ -53,7 +53,10 @@ if (window.telegramEnabled) {
|
|||||||
toggleLoader(waiting);
|
toggleLoader(waiting);
|
||||||
window.telegramModal.show();
|
window.telegramModal.show();
|
||||||
let modalClosed = false;
|
let modalClosed = false;
|
||||||
window.telegramModal.onclose = () => { modalClosed = true; }
|
window.telegramModal.onclose = () => {
|
||||||
|
modalClosed = true;
|
||||||
|
toggleLoader(waiting);
|
||||||
|
}
|
||||||
const checkVerified = () => _get("/invite/" + window.code + "/telegram/verified/" + window.telegramPIN, null, (req: XMLHttpRequest) => {
|
const checkVerified = () => _get("/invite/" + window.code + "/telegram/verified/" + window.telegramPIN, null, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
if (req.status == 401) {
|
if (req.status == 401) {
|
||||||
@ -63,7 +66,6 @@ if (window.telegramEnabled) {
|
|||||||
} else if (req.status == 200) {
|
} else if (req.status == 200) {
|
||||||
if (req.response["success"] as boolean) {
|
if (req.response["success"] as boolean) {
|
||||||
telegramVerified = true;
|
telegramVerified = true;
|
||||||
toggleLoader(waiting);
|
|
||||||
waiting.classList.add("~positive");
|
waiting.classList.add("~positive");
|
||||||
waiting.classList.remove("~info");
|
waiting.classList.remove("~info");
|
||||||
window.notifications.customPositive("telegramVerified", "", window.messages["telegramVerified"]);
|
window.notifications.customPositive("telegramVerified", "", window.messages["telegramVerified"]);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { _get, _post, _delete, toggleLoader, toDateString } from "../modules/common.js";
|
import { _get, _post, _delete, toggleLoader, addLoader, removeLoader, toDateString } from "../modules/common.js";
|
||||||
import { templateEmail } from "../modules/settings.js";
|
import { templateEmail } from "../modules/settings.js";
|
||||||
import { Marked } from "@ts-stack/markdown";
|
import { Marked } from "@ts-stack/markdown";
|
||||||
import { stripMarkdown } from "../modules/stripmd.js";
|
import { stripMarkdown } from "../modules/stripmd.js";
|
||||||
@ -14,6 +14,11 @@ interface User {
|
|||||||
telegram: string;
|
telegram: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface getPinResponse {
|
||||||
|
token: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
class user implements User {
|
class user implements User {
|
||||||
private _row: HTMLTableRowElement;
|
private _row: HTMLTableRowElement;
|
||||||
private _check: HTMLInputElement;
|
private _check: HTMLInputElement;
|
||||||
@ -80,7 +85,8 @@ class user implements User {
|
|||||||
if (!window.telegramEnabled) return;
|
if (!window.telegramEnabled) return;
|
||||||
this._telegramUsername = u;
|
this._telegramUsername = u;
|
||||||
if (u == "") {
|
if (u == "") {
|
||||||
this._telegram.textContent = "";
|
this._telegram.innerHTML = `<span class="chip btn !low">Add</span>`;
|
||||||
|
(this._telegram.querySelector("span") as HTMLSpanElement).onclick = this._addTelegram;
|
||||||
} else {
|
} else {
|
||||||
this._telegram.innerHTML = `<a href="https://t.me/${u}" target="_blank">@${u}</a>`;
|
this._telegram.innerHTML = `<a href="https://t.me/${u}" target="_blank">@${u}</a>`;
|
||||||
}
|
}
|
||||||
@ -193,6 +199,50 @@ class user implements User {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _addTelegram = () => _get("/telegram/pin", null, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState == 4 && req.status == 200) {
|
||||||
|
const pin = document.getElementById("telegram-pin");
|
||||||
|
const link = document.getElementById("telegram-link") as HTMLAnchorElement;
|
||||||
|
const username = document.getElementById("telegram-username") as HTMLSpanElement;
|
||||||
|
const waiting = document.getElementById("telegram-waiting") as HTMLSpanElement;
|
||||||
|
let resp = req.response as getPinResponse;
|
||||||
|
pin.textContent = resp.token;
|
||||||
|
link.href = "https://t.me/" + resp.username;
|
||||||
|
username.textContent = resp.username;
|
||||||
|
addLoader(waiting);
|
||||||
|
let modalClosed = false;
|
||||||
|
window.modals.telegram.onclose = () => {
|
||||||
|
modalClosed = true;
|
||||||
|
removeLoader(waiting);
|
||||||
|
}
|
||||||
|
let send = {
|
||||||
|
token: resp.token,
|
||||||
|
id: this.id
|
||||||
|
};
|
||||||
|
const checkVerified = () => _post("/users/telegram", send, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
if (req.status == 200 && req.response["success"] as boolean) {
|
||||||
|
removeLoader(waiting);
|
||||||
|
waiting.classList.add("~positive");
|
||||||
|
waiting.classList.remove("~info");
|
||||||
|
window.notifications.customSuccess("telegramVerified", window.lang.notif("telegramVerified"));
|
||||||
|
setTimeout(() => {
|
||||||
|
window.modals.telegram.close();
|
||||||
|
waiting.classList.add("~info");
|
||||||
|
waiting.classList.remove("~positive");
|
||||||
|
}, 2000);
|
||||||
|
document.dispatchEvent(new CustomEvent("accounts-reload"));
|
||||||
|
} else if (!modalClosed) {
|
||||||
|
setTimeout(checkVerified, 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
window.modals.telegram.show();
|
||||||
|
checkVerified();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
update = (user: User) => {
|
update = (user: User) => {
|
||||||
this.id = user.id;
|
this.id = user.id;
|
||||||
this.name = user.name;
|
this.name = user.name;
|
||||||
@ -723,6 +773,7 @@ export class accountsList {
|
|||||||
this._selectAll.onchange = () => {
|
this._selectAll.onchange = () => {
|
||||||
this.selectAll = this._selectAll.checked;
|
this.selectAll = this._selectAll.checked;
|
||||||
};
|
};
|
||||||
|
document.addEventListener("accounts-reload", this.reload);
|
||||||
document.addEventListener("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); });
|
document.addEventListener("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); });
|
||||||
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
||||||
this._addUserButton.onclick = window.modals.addUser.toggle;
|
this._addUserButton.onclick = window.modals.addUser.toggle;
|
||||||
|
@ -179,3 +179,22 @@ export function toggleLoader(el: HTMLElement, small: boolean = true) {
|
|||||||
el.appendChild(dot);
|
el.appendChild(dot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addLoader(el: HTMLElement, small: boolean = true) {
|
||||||
|
if (!el.classList.contains("loader")) {
|
||||||
|
el.classList.add("loader");
|
||||||
|
if (small) { el.classList.add("loader-sm"); }
|
||||||
|
const dot = document.createElement("span") as HTMLSpanElement;
|
||||||
|
dot.classList.add("dot")
|
||||||
|
el.appendChild(dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeLoader(el: HTMLElement, small: boolean = true) {
|
||||||
|
if (el.classList.contains("loader")) {
|
||||||
|
el.classList.remove("loader");
|
||||||
|
el.classList.remove("loader-sm");
|
||||||
|
const dot = el.querySelector("span.dot");
|
||||||
|
if (dot) { dot.remove(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@ declare interface Modal {
|
|||||||
show: () => void;
|
show: () => void;
|
||||||
close: (event?: Event) => void;
|
close: (event?: Event) => void;
|
||||||
toggle: () => void;
|
toggle: () => void;
|
||||||
|
onopen: (f: () => void) => void;
|
||||||
|
onclose: (f: () => void) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArrayConstructor {
|
interface ArrayConstructor {
|
||||||
@ -98,6 +100,7 @@ declare interface Modals {
|
|||||||
customizeEmails: Modal;
|
customizeEmails: Modal;
|
||||||
extendExpiry: Modal;
|
extendExpiry: Modal;
|
||||||
updateInfo: Modal;
|
updateInfo: Modal;
|
||||||
|
telegram: Modal;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Invite {
|
interface Invite {
|
||||||
|
Loading…
Reference in New Issue
Block a user