Skip to content
Open

Next #252

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
d849819
update Winston logging framework and unify error handling
Houpert Oct 14, 2025
12a5997
Added a context generator for better log construction
Houpert Oct 16, 2025
2ca761b
Improve log context creation
Houpert Oct 17, 2025
1a8fe2b
Imrpoved context generation and added socket log generation
Houpert Oct 17, 2025
0021458
introduce LogManager to handle context generation and centralized log…
Houpert Oct 20, 2025
df6a304
Improvement of log system
Houpert Oct 22, 2025
4166f60
Handling session watchtime on an activity log
Houpert Oct 23, 2025
a301c3c
Handle socket last disconnect
Houpert Oct 23, 2025
85e9a9d
Clean socket activity logger
Houpert Oct 24, 2025
c09c1d7
Store last organization id in cookie
tjiho Oct 27, 2025
c855f6a
Added llm request logging
Houpert Oct 28, 2025
7ed9ac5
Added transcription logger with metadata
Houpert Oct 28, 2025
679e087
Fix backoffice when owner leave an orga
Houpert Oct 29, 2025
9e6ee63
Show loading state in publish page when status is unknown
tjiho Oct 29, 2025
8975b59
Added an api to list activity log
Houpert Oct 30, 2025
b68a1c0
Remove pdf download on mardown export
tjiho Oct 30, 2025
9275cb1
Fixed export pdf on special character speaker
Houpert Oct 31, 2025
369f915
Fix leaving organization modal
tjiho Oct 31, 2025
ccc930e
Added activity key for session
Houpert Nov 3, 2025
efeab0d
Feature backoffice admin tokens (#244)
tjiho Nov 4, 2025
5c7967a
Remove cloud console front page title
tjiho Nov 4, 2025
ca7ec4e
Init kpi api from activity log
Houpert Nov 4, 2025
981287c
Update session activity rollup for session
Houpert Nov 5, 2025
b684e28
Fixes
tjiho Nov 5, 2025
e5cd6f4
Remove double notification during user update
tjiho Nov 5, 2025
1038b87
Merge pull request #245 from linto-ai/feature-api-logging
Houpert Nov 6, 2025
a644a53
Fix version upgrade vulnerabilities (#246)
Houpert Nov 7, 2025
85b6e70
Handle reconnect to session transcript when device go to sleep
tjiho Nov 7, 2025
1742450
Added nodemon config on package.json
Houpert Nov 7, 2025
aa2a5e1
Fix copy button session channel view
tjiho Nov 7, 2025
80e8999
Fixes in session live
tjiho Nov 7, 2025
de7ec12
Update .envdefault value
Houpert Nov 12, 2025
405a9ab
Upgrade critical front dependencies (#247)
tjiho Nov 12, 2025
d3a3a9f
Feature proxy session administration (#248)
Houpert Nov 13, 2025
f5b4f5c
Feature: protect session with password (#249)
tjiho Nov 20, 2025
6a19d3d
Added an authentication error on private session
Houpert Nov 20, 2025
04ef4ed
Update package-lock for vulnerability
Houpert Nov 20, 2025
596921f
Fixed session status update on public sessions opened by a connected …
tjiho Nov 20, 2025
2f5b327
Fix session permission, ask password only if needed, redirect to 404 …
tjiho Nov 20, 2025
84b9898
Fix permission access on session
Houpert Nov 20, 2025
3d3498b
Set channel name as readonly on session setting page
tjiho Nov 20, 2025
547be0c
Fix quick session websocket
tjiho Nov 21, 2025
71d1227
Fix transcriber profile creation
tjiho Nov 24, 2025
e4e64d9
Fixed translation selection when creating a session in the channel list
tjiho Nov 25, 2025
453030c
Fix: video conference option displayed during microphone setup
tjiho Nov 27, 2025
3052624
Remove leading 0 on media percentage
tjiho Nov 28, 2025
1b9fc58
Release 1.6.1
tjiho Nov 28, 2025
2197ead
Rework quick session (#234)
tjiho Dec 2, 2025
fc9a1b5
Enable diarization by default in quick meeting settings
tjiho Dec 2, 2025
ae240fe
Show more detail on processing step in media listing page
tjiho Dec 3, 2025
3070317
Update sso auth with cookie-session
Houpert Dec 4, 2025
faf10d7
Merge branch 'master' of github.com:linto-ai/linto-studio into next
tjiho Dec 4, 2025
ffac8f1
RELEASE 1.6.1
tjiho Dec 4, 2025
90a2953
Remove session middleware
Houpert Dec 4, 2025
e2beb2a
Set media status as pending is unknown
tjiho Dec 4, 2025
5e4ccc5
Fix closed caption when only bot
Houpert Dec 4, 2025
73d1881
Fix status progress for quick meeting
tjiho Dec 4, 2025
60c2fb5
Improve channel naming on media editor
tjiho Dec 4, 2025
9020014
Handle encryption of cookie during sso process
Houpert Dec 5, 2025
4fa4814
Added encryption key in envdefault for sso auth
Houpert Dec 5, 2025
73c2d4e
Fix api key token expiration
Houpert Dec 12, 2025
c46c772
Fix authentication
Houpert Dec 15, 2025
0887d94
KPI and activity logs
Houpert Dec 16, 2025
42dfd07
Fix the formatedUrl component if the base API is a relative path
tjiho Dec 16, 2025
25c676a
Format duration displayed in session activity log
tjiho Dec 16, 2025
6ab5254
Fix query to find new session with activity
Houpert Dec 16, 2025
d6a18f4
Remove activity session detail tab
tjiho Dec 16, 2025
b92c7b5
Merge branch 'next' of github.com:linto-ai/linto-studio into next
tjiho Dec 16, 2025
77d1932
Remove duplicate api log activity for proxy
Houpert Dec 16, 2025
6378db3
Fix duplicate activity log
Houpert Dec 17, 2025
aeb79fd
Wake lock implementation on live session
tjiho Dec 17, 2025
f709b7b
Merge branch 'next' of github.com:linto-ai/linto-studio into next
tjiho Dec 17, 2025
833add8
Improvment of log duplication error
Houpert Dec 17, 2025
9c813b4
Add mediaCount on orga listing in backoffice
Houpert Dec 17, 2025
3baca4f
Improve media editor navigation when words has no timestamps
tjiho Dec 18, 2025
8cf0889
Merge branch 'next' of github.com:linto-ai/linto-studio into next
tjiho Dec 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 1.6.1

_2025_12_04_

- Public sessions can now be password protected
- User actions are now logged in the database
- Live updating has been improved, with reconnection and better error handling
- External dependencies have been updated to fix vulnerabilities
- SSO functionality now uses an internal cookie-based system making the API sessionless
- Improve microphone and videoconference recording interface

# 1.6.0

_2025_10_08_
Expand Down
4 changes: 3 additions & 1 deletion studio-api/.envdefault
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ DB_PASS=example
DB_NAME=conversations

# Request a specific version of the database (optional)
DB_MIGRATION_TARGET=1.6.1
DB_MIGRATION_TARGET=1.6.2

# STT Config
GATEWAY_SERVICES=https://<domain>
Expand Down Expand Up @@ -97,6 +97,8 @@ JWT_ALGORITHM=HS256
LOCAL_AUTH_ENABLED=true

# OIDC Type supported are : linagora
SSO_ENCRYPTION_KEY=defaultEncryptionKeyChangeMe

OIDC_TYPE=
OIDC_ISSUER_URL=
OIDC_URL=
Expand Down
33 changes: 18 additions & 15 deletions studio-api/components/IoHandler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,54 +31,52 @@ async function checkSocketAccess(socket, roomId) {
const sessionRoomId = roomId.split("/")[0]

try {
// Load session
const sessionRes = await axios.get(
`${process.env.SESSION_API_ENDPOINT}/sessions/${sessionRoomId}`,
)
const session = sessionRes?.data ?? sessionRes

// Check user auth
const { isAuth, userId, sessionId } =
await auth_middlewares.checkSocket(socket)

// Protected session data
const protectedSession =
await model.sessionData.getBySessionId(sessionRoomId)
const hasPassword =
protectedSession?.[0]?.password && protectedSession.length > 0

// Public session + no protection
if (session.visibility === "public" && !hasPassword) {
return true
return { allowed: true, userId }
}

// User is not authenticated
if (!isAuth) {
return denySocket(socket)
denySocket(socket)
return { allowed: false, userId: undefined }
}

// Public session & sessionId matches with a password
// Public session + password-protected, sessionId matches
if (
session.visibility === "public" &&
sessionId === session.id &&
hasPassword
) {
return true
return { allowed: true, userId }
}

// Determine user access from organization access
// Organization access
const access = await sessionSocketAccess(session, userId)
if (access === true) {
// if (session.visibility === "organization") {
return true
return { allowed: true, userId }
}

// Private & owner or explicitly granted access
// Private session & is owner
if (session.visibility === "private" && session.owner === userId) {
return true
return { allowed: true, userId }
}

return denySocket(socket)
denySocket(socket)
return { allowed: false, userId: undefined }
} catch (err) {
LogManager.logSocketEvent(
socket,
Expand All @@ -90,9 +88,11 @@ async function checkSocketAccess(socket, roomId) {
},
{ level: "error" },
)
return denySocket(socket)
denySocket(socket)
return { allowed: false, userId: undefined }
}
}

class IoHandler extends Component {
constructor(app) {
super(app, "WebServer") // Relies on a WebServer component to be registrated
Expand Down Expand Up @@ -130,12 +130,15 @@ class IoHandler extends Component {
}

socket.on("join_room", async (roomId) => {
if (!(await checkSocketAccess(socket, roomId))) return
const { allowed, userId } = await checkSocketAccess(socket, roomId)
if (!allowed) return
LogManager.logSocketEvent(socket, {
sessionId: roomId,
userId,
action: SOCKET_EVENTS.JOIN,
from: "session",
})

this.addSocketInRoom(roomId, socket)
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const debug = require("debug")(
`linto:components:MongoMigration:controllers:schema:activityLog`,
)

module.exports = async function (db, collectionName) {
try {
if (!collectionName) return
const collection = db.collection(collectionName)

await collection.createIndex(
{ timestamp: 1 },
{ expireAfterSeconds: 60 * 60 * 24 * 365 }, // 1 year in ms
)

await collection.createIndex({ "http.status": 1 })
await collection.createIndex({ "user.id": 1 })
await collection.createIndex({ scope: 1 })
await collection.createIndex({ source: 1 })

await collection.createIndex({
timestamp: -1,
"user.id": 1,
})

await collection.createIndex({
timestamp: -1,
"organization.id": 1,
})

console.log(
`Collection "${collectionName}" with TTL index created successfully.`,
)
} catch (error) {
console.error("Error creating collection:", error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ module.exports = async function (db, collectionName) {
if (!collectionName) return
await db
.collection(collectionName)
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 1209600 }) // 14 days in seconds
.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 })

const indexes = await db.collection(collectionName).indexes()
indexes.map(async (index) => {
if (index.name === "createdAt_1") {
await db.collection(collectionName).dropIndex("createdAt_1")
}
})

console.log(
`Collection "${collectionName}" with TTL index created successfully.`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const debug = require("debug")(
`linto:components:MongoMigration:controllers:version:1.1.2:organization`,
`linto:components:MongoMigration:controllers:version:1.1.2:token`,
)

const collections_name = "tokens"
Expand Down
19 changes: 19 additions & 0 deletions studio-api/components/MongoMigration/version/1.6.2/activityLog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const debug = require("debug")(
`linto:components:MongoMigration:controllers:version:1.6.2:activityLog`,
)

const collections_name = "activityLog"

const initIndexActivity = require(
`${process.cwd()}/components/MongoMigration/controllers/schema/activityLog`,
)

module.exports = {
async up(db) {
await initIndexActivity(db, collections_name)
},

async down(db) {
// No lower version for this migration
},
}
19 changes: 19 additions & 0 deletions studio-api/components/MongoMigration/version/1.6.2/token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const debug = require("debug")(
`linto:components:MongoMigration:controllers:version:1.6.2:token`,
)

const collections_name = "tokens"

const initToken = require(
`${process.cwd()}/components/MongoMigration/controllers/schema/tokens`,
)

module.exports = {
async up(db) {
await initToken(db, collections_name)
},

async down(db) {
// No lower version for this migration
},
}
20 changes: 20 additions & 0 deletions studio-api/components/MongoMigration/version/1.6.2/version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const debug = require("debug")(
`linto:components:MongoMigration:controllers:version:1.5.6:version`,
)

const previous_version = "1.6.1"
const version = "1.6.2"

module.exports = {
async up(db) {
return db
.collection("version")
.updateMany({}, { $set: { version: version } })
},

async down(db) {
return db
.collection("version")
.updateMany({}, { $set: { version: previous_version } })
},
}
Loading