userpage: add matrix

This commit is contained in:
Harvey Tindall 2023-06-20 13:28:13 +01:00
parent 96c51af15a
commit d509abdd5c
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
6 changed files with 102 additions and 6 deletions

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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()
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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: `<i class="ri-mail-fill ri-lg"></i>`, f: addEditEmail},
{name: "discord", icon: `<i class="ri-discord-fill ri-lg"></i>`, f: (add: boolean) => { discord.onclick(); }},
{name: "telegram", icon: `<i class="ri-telegram-fill ri-lg"></i>`, f: (add: boolean) => { telegram.onclick() }},
{name: "matrix", icon: `<span class="font-bold">[m]</span>`, f: null}
{name: "matrix", icon: `<span class="font-bold">[m]</span>`, f: (add: boolean) => { matrix.show(); }}
];
for (let method of contactMethods) {