Emby: Integrate LDAP password reset

Short post on how I integrated ltb-projects self service password into my Emby. This was more of lets see if I can do it then having an actual need for it.

Since I hooked up my Emby to LLDAP I noticed the password reset in Emby does not work for LDAP accounts. After a quick trip to the Emby forums it was pretty clear support for it wasn’t coming anytime soon. Since I recently setup a self service page for password resets and changes I wanted to see if I could integrate this into emby.

Since I run Emby in a container (linuxserver image) I had to pull out 2 files:

  • /app/emby/dashboard-ui/startup/manuallogin.html
  • /app/emby/dashboard-ui/settings/password.html

The first is to modify the default login screen.
The second one is the password page you can get to to change your password once logged in.

One thing to note is that the Emby code doesn’t like quick modifications.
So deleting or modifying the existing button and forms was a no go.

In Emby you can inject custom css from the server dashboard settings page. I used this to hide the existing button on the login screen and to hide the forms on the password page.

/*Hide Forgot Password on Login page*/
[data-type="ForgotPassword"] {display: none; }
/*Hide Forgot Password on Manual Login page*/
button.raised.cancel.block.btnForgotPassword.emby-button {display: none; }

/*Hide Change Password on password page*/
form.updatePasswordForm.passwordSection.userProfileSettingsForm.auto-center.padded-top {display: none; }
/*Hide Local Network Access*/
form.localAccessForm.localAccessSection.auto-center {display: none;


With the original button hidden and following html code added to manuallogin.html the user won’t see a difference. We basically create a plain html link and attach some emby css classes to it.
You can find the full code of these pages at the bottom of this post.

<a is="emby-button" class="raised block emby-button" href="https://xxxxx.xxxxx.xxxx" target="_blank">Reset Password</a>

Embedding our ssp page in the password area went a lot easier then expected. After hiding the forms I could simply use an html embed to insert the complete page.

<embed type="text/html" src="https://xxxxx.xxxxxx.xxx/" width="800" height="900">
<div is="emby-scroller" class="view flex flex-direction-column scrollFrameY flex-grow" data-mousewheel="true" data-horizontal="false" data-forcescrollbar="true" data-centerfocus="card" data-bindheader="true">
    <div class="scrollSlider flex-grow flex-direction-column padded-left padded-right padded-top-page padded-bottom-page">
        <form style="margin:0 auto;">

            <h1 style="margin-top:0;">${HeaderPleaseSignIn}</h1>

            <div class="inputContainer">
                <input is="emby-input" class="txtUserName" type="text" id="txtUserName" autocomplete="off" label="${LabelUsername}" required />
            </div>
            <div class="inputContainer">
                <input is="emby-input" class="txtPassword" type="password" id="txtPassword" autocomplete="off" label="${LabelPassword}" />
            </div>
            <label class="checkboxContainer">
                <input is="emby-checkbox" type="checkbox" class="chkRememberLogin" checked />
                <span>${RememberMe}</span>
            </label>
            <button is="emby-button" type="submit" class="raised block paperSubmit">
                <span>${HeaderSignIn}</span>
            </button>
            <button is="emby-button" type="button" class="raised block buttonCancel">
                <span>${Cancel}</span>
            </button>

            <div style="margin-top:2em;">
                <button is="emby-button" type="button" class="raised cancel block btnForgotPassword">
                    <span>${HeaderForgotPassword}</span>
                </button>

                <button is="emby-button" type="button" class="raised hide block btnSelectServer">
                    <span>${HeaderChangeServer}</span>
                </button>

                <a is="emby-button" class="raised block emby-button" href="https://xxxxx.xxxxx.xxx/" target="_blank">JellySeerr</a>
                <a is="emby-button" class="raised block emby-button" href="https://xxxxx.xxxxx.xxxx" target="_blank">Reset Password</a>
                <p class="disclaimer" style="text-align: center; margin-top: 2em;"></p>
            </div>

        </form>
    </div>
</div>
<div is="emby-scroller" class="view flex flex-direction-column scrollFrameY flex-grow" data-mousewheel="true" data-horizontal="false" data-forcescrollbar="true" data-centerfocus="card" data-bindheader="true">
    
    <div class="scrollSlider flex-grow flex-direction-column padded-left padded-left-page padded-right padded-top-page padded-bottom-page settingsContainer">
        <form class="updatePasswordForm passwordSection userProfileSettingsForm hide auto-center padded-top">

            <div class="verticalSection">

                <div class="fldCurrentPassword inputContainer hide">
                    <input is="emby-input" type="password" class="txtCurrentPassword" label="${LabelCurrentPassword}" autocomplete="off" />
                </div>
                <div class="inputContainer">
                    <input is="emby-input" type="password" class="txtNewPassword" label="${LabelNewPassword}" autocomplete="off" />
                </div>
                <div class="inputContainer">
                    <input is="emby-input" type="password" class="txtNewPasswordConfirm" label="${LabelNewPasswordConfirm}" autocomplete="off" />
                </div>
                <div>
                    <button is="emby-button" type="submit" class="raised button-submit block"><span>${Save}</span></button>
                </div>
                <button is="emby-button" type="button" class="btnResetPassword raised button-cancel block hide">
                    <span>${HeaderRemovePassword}</span>
                </button>
            </div>
        </form>
        <form class="localAccessForm localAccessSection auto-center" style="margin-top: 3em;">
            <div class="detailSection">
                <h2 class="detailSectionHeader">
                    ${HeaderLocalNetworkAccess}
                </h2>
                <div class="selectContainer fldInNetworkPasswordMode">
                    <select is="emby-select" class="selectInNetworkPasswordMode" label="${LabelLocalNetworkPasswordMode}">
                        <option value="password">${RequirePasswordInLocalNetwork}</option>
                        <option value="nopassword">${NoPasswordInLocalNetwork}</option>
                        <option value="pin">${PinCodeInLocalNetwork}</option>
                    </select>
                    <div class="fieldDescription">${LocalNetworkPasswordModeHelp}</div>
                </div>
                <div class="inputContainer fldInNetworkPassword hide">
                    <input placeholder="*****" is="emby-input" type="number" class="txtInNetworkPassword" label="${LabelLocalNetworkPinCode}" autocomplete="off" pattern="[0-9]*" step="1" maxlength="5" />
                </div>
                <div>
                    <button is="emby-button" type="submit" class="raised button-submit block">
                        <span>${Save}</span>
                    </button>
                </div>
            </div>
        </form>
        <embed type="text/html" src="https://xxxxx.xxxxxx.xxx/" width="800" height="900">
    </div>
Leave A Comment

Your email address will not be published. Required fields are marked *