mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-01-01 04:00:45 -05:00
Compare commits
6 Commits
localize_d
...
session_mo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e678fe6e2f | ||
|
|
3845940245 | ||
|
|
6c63e2131c | ||
|
|
e25e2b238f | ||
|
|
b553e959e2 | ||
|
|
f7b94a4b6d |
@@ -81,7 +81,7 @@
|
||||
</div>
|
||||
<div class="w-full md:w-1/3">
|
||||
<p v-if="!isMediaItemShareSession" class="font-semibold uppercase text-xs text-gray-400 tracking-wide mb-2 mt-6 md:mt-0">{{ $strings.LabelUser }}</p>
|
||||
<p v-if="!isMediaItemShareSession" class="mb-1 text-xs">{{ _session.userId }}</p>
|
||||
<p v-if="!isMediaItemShareSession" class="mb-1 text-xs">{{ username }}</p>
|
||||
|
||||
<p class="font-semibold uppercase text-xs text-gray-400 tracking-wide mt-6 mb-2">{{ $strings.LabelMediaPlayer }}</p>
|
||||
<p class="mb-1">{{ playMethodName }}</p>
|
||||
@@ -132,6 +132,9 @@ export default {
|
||||
_session() {
|
||||
return this.session || {}
|
||||
},
|
||||
username() {
|
||||
return this._session.user?.username || this._session.userId || ''
|
||||
},
|
||||
deviceInfo() {
|
||||
return this._session.deviceInfo || {}
|
||||
},
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
<widgets-online-indicator :value="!!userOnline" />
|
||||
<h1 class="text-xl pl-2">{{ username }}</h1>
|
||||
</div>
|
||||
<div v-if="legacyToken" class="flex text-xs mt-4">
|
||||
<div v-if="legacyToken" class="text-xs space-y-2 mt-4">
|
||||
<ui-text-input-with-label label="Legacy API Token" :value="legacyToken" readonly show-copy />
|
||||
|
||||
<p class="text-warning" v-html="$strings.MessageAuthenticationLegacyTokenWarning" />
|
||||
</div>
|
||||
<div class="w-full h-px bg-white/10 my-2" />
|
||||
<div class="py-2">
|
||||
|
||||
@@ -723,6 +723,7 @@
|
||||
"MessageAddToPlayerQueue": "Add to player queue",
|
||||
"MessageAppriseDescription": "To use this feature you will need to have an instance of <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> running or an api that will handle those same requests. <br />The Apprise API Url should be the full URL path to send the notification, e.g., if your API instance is served at <code>http://192.168.1.1:8337</code> then you would put <code>http://192.168.1.1:8337/notify</code>.",
|
||||
"MessageAsinCheck": "Ensure you are using the ASIN from the correct Audible region, not Amazon.",
|
||||
"MessageAuthenticationLegacyTokenWarning": "Legacy API tokens will be removed in the future. Use <a href=\"/config/api-keys\">API Keys</a> instead.",
|
||||
"MessageAuthenticationOIDCChangesRestart": "Restart your server after saving to apply OIDC changes.",
|
||||
"MessageAuthenticationSecurityMessage": "Authentication has been improved for security. All users are required to re-login.",
|
||||
"MessageBackupsDescription": "Backups include users, user progress, library item details, server settings, and images stored in <code>/metadata/items</code> & <code>/metadata/authors</code>. Backups <strong>do not</strong> include any files stored in your library folders.",
|
||||
|
||||
@@ -240,7 +240,7 @@ class Server {
|
||||
* Running in development allows cors to allow testing the mobile apps in the browser
|
||||
* or env variable ALLOW_CORS = '1'
|
||||
*/
|
||||
if (Logger.isDev || req.path.match(/\/api\/items\/([a-z0-9-]{36})\/(ebook|cover)(\/[0-9]+)?/)) {
|
||||
if (global.AllowCors || Logger.isDev || req.path.match(/\/api\/items\/([a-z0-9-]{36})\/(ebook|cover)(\/[0-9]+)?/)) {
|
||||
const allowedOrigins = ['capacitor://localhost', 'http://localhost']
|
||||
if (global.AllowCors || Logger.isDev || allowedOrigins.some((o) => o === req.get('origin'))) {
|
||||
res.header('Access-Control-Allow-Origin', req.get('origin'))
|
||||
|
||||
@@ -121,7 +121,7 @@ class OidcAuthStrategy {
|
||||
throw new Error(`Group claim ${Database.serverSettings.authOpenIDGroupClaim} not found or empty in userinfo`)
|
||||
}
|
||||
|
||||
let user = await Database.userModel.findOrCreateUserFromOpenIdUserInfo(userinfo, this)
|
||||
let user = await Database.userModel.findOrCreateUserFromOpenIdUserInfo(userinfo)
|
||||
|
||||
if (!user?.isActive) {
|
||||
throw new Error('User not active or not found')
|
||||
|
||||
@@ -81,6 +81,18 @@ class TokenManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JWT token for a given user
|
||||
* TODO: Old method with no expiration
|
||||
* @deprecated
|
||||
*
|
||||
* @param {{ id:string, username:string }} user
|
||||
* @returns {string}
|
||||
*/
|
||||
static generateAccessToken(user) {
|
||||
return jwt.sign({ userId: user.id, username: user.username }, TokenManager.TokenSecret)
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to generate a jwt token for a given user
|
||||
* TODO: Old method with no expiration
|
||||
@@ -90,7 +102,7 @@ class TokenManager {
|
||||
* @returns {string}
|
||||
*/
|
||||
generateAccessToken(user) {
|
||||
return jwt.sign({ userId: user.id, username: user.username }, TokenManager.TokenSecret)
|
||||
return TokenManager.generateAccessToken(user)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,26 +57,24 @@ class SessionController {
|
||||
}
|
||||
|
||||
let where = null
|
||||
const include = [
|
||||
{
|
||||
model: Database.models.device
|
||||
}
|
||||
]
|
||||
|
||||
if (userId) {
|
||||
where = {
|
||||
userId
|
||||
}
|
||||
} else {
|
||||
include.push({
|
||||
model: Database.userModel,
|
||||
attributes: ['id', 'username']
|
||||
})
|
||||
}
|
||||
|
||||
const { rows, count } = await Database.playbackSessionModel.findAndCountAll({
|
||||
where,
|
||||
include,
|
||||
include: [
|
||||
{
|
||||
model: Database.deviceModel
|
||||
},
|
||||
{
|
||||
model: Database.userModel,
|
||||
attributes: ['id', 'username']
|
||||
}
|
||||
],
|
||||
order: [[orderKey, orderDesc]],
|
||||
limit: itemsPerPage,
|
||||
offset: itemsPerPage * page
|
||||
|
||||
@@ -439,7 +439,16 @@ class UserController {
|
||||
const page = toNumber(req.query.page, 0)
|
||||
|
||||
const start = page * itemsPerPage
|
||||
const sessions = listeningSessions.slice(start, start + itemsPerPage)
|
||||
// Map user to sessions to match the format of the sessions endpoint
|
||||
const sessions = listeningSessions.slice(start, start + itemsPerPage).map((session) => {
|
||||
return {
|
||||
...session,
|
||||
user: {
|
||||
id: req.reqUser.id,
|
||||
username: req.reqUser.username
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const payload = {
|
||||
total: listeningSessions.length,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
const uuidv4 = require('uuid').v4
|
||||
const sequelize = require('sequelize')
|
||||
const { LRUCache } = require('lru-cache')
|
||||
|
||||
const Logger = require('../Logger')
|
||||
const SocketAuthority = require('../SocketAuthority')
|
||||
const { isNullOrNaN } = require('../utils')
|
||||
const { LRUCache } = require('lru-cache')
|
||||
const TokenManager = require('../auth/TokenManager')
|
||||
|
||||
class UserCache {
|
||||
constructor() {
|
||||
@@ -213,10 +215,9 @@ class User extends Model {
|
||||
* or creates a new user if configured to do so.
|
||||
*
|
||||
* @param {Object} userinfo
|
||||
* @param {import('../Auth')} auth
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
static async findOrCreateUserFromOpenIdUserInfo(userinfo, auth) {
|
||||
static async findOrCreateUserFromOpenIdUserInfo(userinfo) {
|
||||
let user = await this.getUserByOpenIDSub(userinfo.sub)
|
||||
|
||||
// Matched by sub
|
||||
@@ -290,7 +291,7 @@ class User extends Model {
|
||||
// If no existing user was matched, auto-register if configured
|
||||
if (global.ServerSettings.authOpenIDAutoRegister) {
|
||||
Logger.info(`[User] openid: Auto-registering user with sub "${userinfo.sub}"`, userinfo)
|
||||
user = await this.createUserFromOpenIdUserInfo(userinfo, auth)
|
||||
user = await this.createUserFromOpenIdUserInfo(userinfo)
|
||||
return user
|
||||
}
|
||||
|
||||
@@ -301,16 +302,15 @@ class User extends Model {
|
||||
/**
|
||||
* Create user from openid userinfo
|
||||
* @param {Object} userinfo
|
||||
* @param {import('../Auth')} auth
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
static async createUserFromOpenIdUserInfo(userinfo, auth) {
|
||||
static async createUserFromOpenIdUserInfo(userinfo) {
|
||||
const userId = uuidv4()
|
||||
// TODO: Ensure username is unique?
|
||||
const username = userinfo.preferred_username || userinfo.name || userinfo.sub
|
||||
const email = userinfo.email && userinfo.email_verified ? userinfo.email : null
|
||||
|
||||
const token = auth.generateAccessToken({ id: userId, username })
|
||||
const token = TokenManager.generateAccessToken({ id: userId, username })
|
||||
|
||||
const newUser = {
|
||||
id: userId,
|
||||
|
||||
Reference in New Issue
Block a user