diff --git a/api-userpage.go b/api-userpage.go
index b63199d..4a84949 100644
--- a/api-userpage.go
+++ b/api-userpage.go
@@ -10,7 +10,7 @@ import (
"github.com/golang-jwt/jwt"
)
-// @Summary Returns the logged-in user's Jellyfin ID & Username.
+// @Summary Returns the logged-in user's Jellyfin ID & Username, and other details.
// @Produce json
// @Success 200 {object} MyDetailsDTO
// @Router /my/details [get]
@@ -379,3 +379,73 @@ func (app *appContext) MyTelegramVerifiedInvite(gc *gin.Context) {
app.storage.SetTelegramKey(gc.GetString("jfId"), tgUser)
respondBool(200, true, gc)
}
+
+// @Summary Generate and send a new PIN to your given matrix user.
+// @Produce json
+// @Success 200 {object} boolResponse
+// @Failure 400 {object} stringResponse
+// @Failure 401 {object} boolResponse
+// @Failure 500 {object} boolResponse
+// @Param MatrixSendPINDTO body MatrixSendPINDTO true "User's Matrix ID."
+// @Router /my/matrix/user [post]
+// @tags User Page
+func (app *appContext) MatrixSendMyPIN(gc *gin.Context) {
+ var req MatrixSendPINDTO
+ gc.BindJSON(&req)
+ if req.UserID == "" {
+ respond(400, "errorNoUserID", gc)
+ return
+ }
+ if app.config.Section("matrix").Key("require_unique").MustBool(false) {
+ for _, u := range app.storage.GetMatrix() {
+ if req.UserID == u.UserID {
+ respondBool(400, false, gc)
+ return
+ }
+ }
+ }
+
+ ok := app.matrix.SendStart(req.UserID)
+ if !ok {
+ respondBool(500, false, gc)
+ return
+ }
+ respondBool(200, true, gc)
+}
+
+// @Summary Check whether your matrix PIN is valid, and link the account to yours if so.
+// @Produce json
+// @Success 200 {object} boolResponse
+// @Failure 401 {object} boolResponse
+// @Param pin path string true "PIN code to check"
+// @Param invCode path string true "invite Code"
+// @Param userID path string true "Matrix User ID"
+// @Router /my/matrix/verified/{userID}/{pin} [get]
+// @tags User Page
+func (app *appContext) MatrixCheckMyPIN(gc *gin.Context) {
+ userID := gc.Param("userID")
+ pin := gc.Param("pin")
+ user, ok := app.matrix.tokens[pin]
+ if !ok {
+ app.debug.Println("Matrix: PIN not found")
+ respondBool(200, false, gc)
+ return
+ }
+ if user.User.UserID != userID {
+ app.debug.Println("Matrix: User ID of PIN didn't match")
+ respondBool(200, false, gc)
+ return
+ }
+
+ mxUser := *user.User
+ mxUser.Contact = true
+ existingUser, ok := app.storage.GetMatrixKey(gc.GetString("jfId"))
+ if ok {
+ mxUser.Lang = existingUser.Lang
+ mxUser.Contact = existingUser.Contact
+ }
+
+ app.storage.SetMatrixKey(gc.GetString("jfId"), mxUser)
+ delete(app.matrix.tokens, pin)
+ respondBool(200, true, gc)
+}
diff --git a/router.go b/router.go
index b1b5b95..18e3814 100644
--- a/router.go
+++ b/router.go
@@ -235,6 +235,8 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
user.GET(p+"/pin/:service", app.GetMyPIN)
user.GET(p+"/discord/verified/:pin", app.MyDiscordVerifiedInvite)
user.GET(p+"/telegram/verified/:pin", app.MyTelegramVerifiedInvite)
+ user.POST(p+"/matrix/user", app.MatrixSendMyPIN)
+ user.POST(p+"/matrix/verified/:userID/:pin", app.MatrixCheckMyPIN)
}
}
}
diff --git a/storage.go b/storage.go
index 605516e..d24b960 100644
--- a/storage.go
+++ b/storage.go
@@ -63,6 +63,7 @@ func (st *Storage) SetEmailsKey(k string, v EmailAddress) {
func (st *Storage) DeleteEmailsKey(k string) {
st.emailsLock.Lock()
delete(st.emails, k)
+ st.storeEmails()
st.emailsLock.Unlock()
}
@@ -89,6 +90,7 @@ func (st *Storage) SetDiscordKey(k string, v DiscordUser) {
func (st *Storage) DeleteDiscordKey(k string) {
st.discordLock.Lock()
delete(st.discord, k)
+ st.storeDiscordUsers()
st.discordLock.Unlock()
}
@@ -115,6 +117,7 @@ func (st *Storage) SetTelegramKey(k string, v TelegramUser) {
func (st *Storage) DeleteTelegramKey(k string) {
st.telegramLock.Lock()
delete(st.telegram, k)
+ st.storeTelegramUsers()
st.telegramLock.Unlock()
}
@@ -141,6 +144,7 @@ func (st *Storage) SetMatrixKey(k string, v MatrixUser) {
func (st *Storage) DeleteMatrixKey(k string) {
st.matrixLock.Lock()
delete(st.matrix, k)
+ st.storeMatrixUsers()
st.matrixLock.Unlock()
}
diff --git a/ts/form.ts b/ts/form.ts
index 3722c23..961de8a 100644
--- a/ts/form.ts
+++ b/ts/form.ts
@@ -121,6 +121,7 @@ if (window.matrixEnabled) {
verifiedURL: "/invite/" + window.code + "/matrix/verified/",
invalidCodeError: window.messages["errorInvalidPIN"],
accountLinkedError: window.messages["errorAccountLinked"],
+ unknownError: window.messages["errorUnknown"],
successError: window.messages["verified"],
successFunc: () => {
matrixVerified = true;
diff --git a/ts/modules/account-linking.ts b/ts/modules/account-linking.ts
index d14fcbb..ea3994f 100644
--- a/ts/modules/account-linking.ts
+++ b/ts/modules/account-linking.ts
@@ -188,7 +188,7 @@ export class Matrix {
private _conf: MatrixConfiguration;
private _verified = false;
private _name: string = "matrix";
- private _userID: string;
+ private _userID: string = "";
private _pin: string = "";
private _input: HTMLInputElement;
private _submit: HTMLSpanElement;
@@ -212,7 +212,10 @@ export class Matrix {
}
};
- show = () => { this._conf.modal.show(); }
+ show = () => {
+ this._input.value = "";
+ this._conf.modal.show();
+ }
private _sendMessage = () => _post(this._conf.sendMessageURL, { "user_id": this._input.value }, (req: XMLHttpRequest) => {
if (req.readyState != 4) return;
@@ -258,6 +261,6 @@ export class Matrix {
this._submit.classList.remove("~critical");
}, 800);
}
- });
+ }, true);
}
diff --git a/ts/user.ts b/ts/user.ts
index 7c334d8..1983d66 100644
--- a/ts/user.ts
+++ b/ts/user.ts
@@ -3,7 +3,7 @@ import { lang, LangFile, loadLangSelector } from "./modules/lang.js";
import { Modal } from "./modules/modal.js";
import { _get, _post, notificationBox, whichAnimationEvent, toDateString, toggleLoader } from "./modules/common.js";
import { Login } from "./modules/login.js";
-import { Discord, Telegram, ServiceConfiguration } from "./modules/account-linking.js";
+import { Discord, Telegram, Matrix, ServiceConfiguration, MatrixConfiguration } from "./modules/account-linking.js";
interface userWindow extends Window {
jellyfinID: string;
@@ -316,6 +316,22 @@ const telegramConf: ServiceConfiguration = {
let telegram = new Telegram(telegramConf);
+const matrixConf: MatrixConfiguration = {
+ modal: window.modals.matrix as Modal,
+ sendMessageURL: "/my/matrix/user",
+ verifiedURL: "/my/matrix/verified/",
+ invalidCodeError: window.lang.notif("errorInvalidPIN"),
+ accountLinkedError: window.lang.notif("errorAccountLinked"),
+ unknownError: window.lang.notif("errorUnknown"),
+ successError: window.lang.notif("verified"),
+ successFunc: () => {
+ setTimeout(() => window.location.reload(), 1200);
+ }
+};
+
+let matrix = new Matrix(matrixConf);
+
+
document.addEventListener("details-reload", () => {
_get("/my/details", null, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
@@ -347,7 +363,7 @@ document.addEventListener("details-reload", () => {
{name: "email", icon: ``, f: addEditEmail},
{name: "discord", icon: ``, f: (add: boolean) => { discord.onclick(); }},
{name: "telegram", icon: ``, f: (add: boolean) => { telegram.onclick() }},
- {name: "matrix", icon: `[m]`, f: null}
+ {name: "matrix", icon: `[m]`, f: (add: boolean) => { matrix.show(); }}
];
for (let method of contactMethods) {