Compare commits

..

7 Commits

38 changed files with 390 additions and 312 deletions

View File

@ -3,10 +3,10 @@ name: Artifact Csharp MVC
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/csharp-mvc/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/csharp-mvc/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Csharp
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/csharp/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/csharp/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Golang
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/go/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/go/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Java
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/java/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/java/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Nodejs
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/nodejs/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/nodejs/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact PHP Laravel
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/php-laravel/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/php-laravel/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact PHP
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/php/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/php/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Python
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/python/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/python/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Ruby
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/ruby/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/ruby/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Artifact Java Spring
on:
workflow_dispatch:
push:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/java-spring/**']
pull_request:
branches: [main]
branches: [master]
paths: ['web/documentserver-example/java-spring/**']
jobs:

View File

@ -2,7 +2,7 @@ name: Create Tag
on:
push:
branches: [main]
branches: [master]
paths-ignore:
- '.github/**'
- '**/AUTHORS.md'

View File

@ -3,10 +3,10 @@ name: Licenses Csharp MVC
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/csharp-mvc/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/csharp-mvc/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Csharp
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/csharp/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/csharp/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Go
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/go/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/go/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Java
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Nodejs
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/nodejs/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/nodejs/**']
env:

View File

@ -3,10 +3,10 @@ name: Licenses PHP Laravel
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php-laravel/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php-laravel/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses PHP
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Python
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/python/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/python/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Ruby
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/ruby/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/ruby/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Licenses Java Spring
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java-spring/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java-spring/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Golangci
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/go/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/go/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Lint Java
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/java/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java/**']
jobs:

View File

@ -3,10 +3,10 @@ name: ESLint
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/nodejs/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/nodejs/**']
env:

View File

@ -3,10 +3,10 @@ name: Laravel Pint
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/php-laravel/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php-laravel/**']
jobs:

View File

@ -3,10 +3,10 @@ name: PHPCs
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/php/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/php/**']
jobs:

View File

@ -3,10 +3,10 @@ name: PyLint
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/python/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/python/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Rubocop
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/ruby/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/ruby/**']
jobs:

View File

@ -3,10 +3,10 @@ name: Lint Spring
on:
workflow_dispatch:
push:
branches: [main, develop]
branches: [master]
paths: ['web/documentserver-example/java-spring/**']
pull_request:
branches: [main, develop]
branches: [master, develop]
paths: ['web/documentserver-example/java-spring/**']
jobs:

View File

@ -1,7 +1,5 @@
# Change Log
- java-spring: docs-integration-sdk updated to 1.8
- php-laravel: update docs-integration-sdk to 1.4
- nodejs: wopi CopyPasteRestrictions for anonymous
- update insertImage formats
- new mobile index page view

View File

@ -8,16 +8,16 @@ These examples show the way to integrate [ONLYOFFICE Docs][2] into your own webs
The package contains examples written in .Net (C# MVC), .Net (C#), Go, Java, Java Spring, Node.js, PHP, PHP (Laravel), Python and Ruby.
You should change `http://documentserver` to your server address in these files:
* [.Net (C# MVC)](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/csharp-mvc) - `web/documentserver-example/csharp-mvc/web.appsettings.config`
* [.Net (C#)](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/csharp) - `web/documentserver-example/csharp/settings.config`
* [Go](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/go) - `web\documentserver-example\go\config\configuration.json`
* [Java](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/java) - `web/documentserver-example/java/src/main/resources/settings.properties`
* [Java Spring](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/java-spring) - `web/documentserver-example/java-spring/src/main/resources/application.properties`
* [Node.js](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/nodejs) - `web/documentserver-example/nodejs/config/default.json`
* [PHP](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/php) - `web/documentserver-example/php/src/configuration/ConfigurationManager.php`
* [PHP (Laravel)](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/php-laravel) - `web/documentserver-example/php-laravel/.env.example`
* [Python](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/python) - `web/documentserver-example/python/src/configuration/configuration.py`
* [Ruby](https://github.com/ONLYOFFICE/document-server-integration/tree/main/web/documentserver-example/ruby) - `web/documentserver-example/ruby/app/configuration/configuration.rb`
* [.Net (C# MVC)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/csharp-mvc) - `web/documentserver-example/csharp-mvc/web.appsettings.config`
* [.Net (C#)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/csharp) - `web/documentserver-example/csharp/settings.config`
* [Go](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/go) - `web\documentserver-example\go\config\configuration.json`
* [Java](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/java) - `web/documentserver-example/java/src/main/resources/settings.properties`
* [Java Spring](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/java-spring) - `web/documentserver-example/java-spring/src/main/resources/application.properties`
* [Node.js](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/nodejs) - `web/documentserver-example/nodejs/config/default.json`
* [PHP](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/php) - `web/documentserver-example/php/src/configuration/ConfigurationManager.php`
* [PHP (Laravel)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/php-laravel) - `web/documentserver-example/php-laravel/.env.example`
* [Python](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/python) - `web/documentserver-example/python/src/configuration/configuration.py`
* [Ruby](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/ruby) - `web/documentserver-example/ruby/app/configuration/configuration.rb`
More information on how to use these examples can be found here: [https://api.onlyoffice.com/docs/docs-api/samples/language-specific-examples/](https://api.onlyoffice.com/docs/docs-api/samples/language-specific-examples/)

View File

@ -84,7 +84,7 @@
<dependency>
<groupId>com.onlyoffice</groupId>
<artifactId>docs-integration-sdk</artifactId>
<version>1.8.0</version>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>

View File

@ -29,7 +29,6 @@ const config = require('config');
const mime = require('mime');
const urllib = require('urllib');
const urlModule = require('url');
const { emitWarning } = require('process');
const DocManager = require('./helpers/docManager');
const documentService = require('./helpers/documentService');
const fileUtility = require('./helpers/fileUtility');
@ -721,12 +720,38 @@ app.put('/restore', async (req, res) => { // define a handler for restore file v
res.end();
});
app.post('/forcesave', async (req, res) => {
req.DocManager = new DocManager(req, res);
const uAddress = req.query.useraddress;
const fName = fileUtility.getFileName(req.query.filename);
if (req.headers['content-type'] === 'application/octet-stream') {
const form = new formidable.IncomingForm();
form.parse(req, async (err, fields, files) => {
if (err) {
res.write('{"error":1, "message":"document data is empty"}');
res.end();
return;
}
const filePath = files.file.filepath || files.file[0].filepath;
const data = fileSystem.readFileSync(filePath);
await req.DocManager.forcesaveFile(data, fName, fileUtility.getFileExtension(fName), uAddress);
fileSystem.unlinkSync(filePath);
res.write('{"error":0}');
res.end();
});
} else {
res.write('{"error":0}');
res.end();
}
});
app.post('/track', async (req, res) => { // define a handler for tracking file changes
req.DocManager = new DocManager(req, res);
let uAddress = req.query.useraddress;
let fName = fileUtility.getFileName(req.query.filename);
let version = 0;
// track file changes
const processTrack = async function processTrack(response, bodyTrack, fileNameTrack, userAddressTrack) {
@ -751,56 +776,7 @@ app.post('/track', async (req, res) => { // define a handler for tracking file c
if (status !== 200) throw new Error(`Document editing service returned status: ${status}`);
const storagePath = req.DocManager.storagePath(newFileName, userAddress);
let historyPath = req.DocManager.historyPath(newFileName, userAddress); // get the path to the history data
if (historyPath === '') { // if the history path doesn't exist
historyPath = req.DocManager.historyPath(newFileName, userAddress, true); // create it
req.DocManager.createDirectory(historyPath); // and create a directory for the history data
}
const countVersion = req.DocManager.countVersion(historyPath); // get the next file version number
version = countVersion + 1;
// get the path to the specified file version
const versionPath = req.DocManager.versionPath(newFileName, userAddress, version);
req.DocManager.createDirectory(versionPath); // create a directory to the specified file version
const downloadZip = body.changesurl;
if (downloadZip) {
// get the path to the file with document versions differences
const pathChanges = req.DocManager.diffPath(newFileName, userAddress, version);
const zip = await urllib.request(downloadZip, { method: 'GET' });
const statusZip = zip.status;
const dataZip = zip.data;
if (statusZip === 200) {
fileSystem.writeFileSync(pathChanges, dataZip); // write the document version differences to the archive
} else {
emitWarning(`Document editing service returned status: ${statusZip}`);
}
}
const changeshistory = JSON.stringify(body.history);
if (changeshistory) {
// get the path to the file with document changes
const pathChangesJson = req.DocManager.changesPath(newFileName, userAddress, version);
fileSystem.writeFileSync(pathChangesJson, changeshistory); // and write this data to the path in json format
}
const pathKey = req.DocManager.keyPath(newFileName, userAddress, version); // get the path to the key.txt file
fileSystem.writeFileSync(pathKey, body.key); // write the key value to the key.txt file
// get the path to the previous file version
const pathPrev = path.join(versionPath, `prev${fileUtility.getFileExtension(fileName)}`);
// and write it to the current path
fileSystem.renameSync(req.DocManager.storagePath(fileName, userAddress), pathPrev);
fileSystem.writeFileSync(storagePath, data);
// get the path to the forcesaved file
const forcesavePath = req.DocManager.forcesavePath(newFileName, userAddress, false);
if (forcesavePath !== '') { // if this path is empty
fileSystem.unlinkSync(forcesavePath); // remove it
}
await req.DocManager.saveFile(fileName, newFileName, userAddress, body, data);
} catch (ex) {
console.log(ex);
response.setHeader('Content-Type', 'application/json');
@ -870,64 +846,8 @@ app.post('/track', async (req, res) => { // define a handler for tracking file c
const downloadExt = `.${body.fileType}`;
const isSubmitForm = body.forcesavetype === 3; // SubmitForm
let correctName = fileName;
let forcesavePath = '';
if (isSubmitForm) {
// new file
if (newFileName) {
correctName = req.DocManager.getCorrectName(
`${fileUtility.getFileName(fileName, true)}-form${downloadExt}`,
userAddress,
);
} else {
const ext = fileUtility.getFileExtension(fileName);
correctName = req.DocManager.getCorrectName(
`${fileUtility.getFileName(fileName, true)}-form${ext}`,
userAddress,
);
}
forcesavePath = req.DocManager.storagePath(correctName, userAddress);
} else {
if (newFileName) {
correctName = req.DocManager.getCorrectName(fileUtility.getFileName(
fileName,
true,
) + downloadExt, userAddress);
}
// create forcesave path if it doesn't exist
forcesavePath = req.DocManager.forcesavePath(correctName, userAddress, false);
if (forcesavePath === '') {
forcesavePath = req.DocManager.forcesavePath(correctName, userAddress, true);
}
}
fileSystem.writeFileSync(forcesavePath, data);
if (isSubmitForm) {
const uid = body.actions[0].userid;
req.DocManager.saveFileData(correctName, uid, 'Filling Form', userAddress);
const { formsdataurl } = body;
if (formsdataurl) {
const formsdataName = req.DocManager.getCorrectName(
`${fileUtility.getFileName(correctName, true)}.txt`,
userAddress,
);
// get the path to the file with forms data
const formsdataPath = req.DocManager.storagePath(formsdataName, userAddress);
const formsdata = await urllib.request(formsdataurl, { method: 'GET' });
const statusFormsdata = formsdata.status;
const dataFormsdata = formsdata.data;
if (statusFormsdata === 200) {
fileSystem.writeFileSync(formsdataPath, dataFormsdata); // write the forms data
} else {
emitWarning(`Document editing service returned status: ${statusFormsdata}`);
}
} else {
emitWarning('Document editing service do not returned formsdataurl');
}
}
await req.DocManager.forcesaveFile(data, fileName, downloadExt, userAddress, body, newFileName, isSubmitForm);
} catch (ex) {
console.log(ex);
response.write(`{ "error":1, "message":${JSON.stringify(ex)} }`);
@ -989,6 +909,9 @@ app.post('/track', async (req, res) => { // define a handler for tracking file c
}
}
}
if (bodyTrack.users.length <= 0 && req.DocManager.forcesavePath(fName, uAddress, false)) {
await req.DocManager.saveFile(fName, fName, uAddress, bodyTrack);
}
} else if (bodyTrack.status === 2 || bodyTrack.status === 3) { // MustSave, Corrupted
await processSave(bodyTrack.url, bodyTrack, fileNameTrack, userAddressTrack); // save file
return;
@ -1107,6 +1030,7 @@ app.get('/editor', (req, res) => { // define a handler for editing document
req.DocManager = new DocManager(req, res);
let { fileExt } = req.query;
const fromBuffer = req.query.fromBuffer === 'true';
const user = users.getUser(req.query.userid);
const userid = user.id;
const { name } = user;
@ -1250,11 +1174,12 @@ app.get('/editor', (req, res) => { // define a handler for editing document
// file config data
const argss = {
bufferCallback: req.DocManager.getCallback(fileName, fromBuffer),
apiUrl: siteUrl + configServer.get('apiUrl'),
file: {
name: fileName,
ext: fileUtility.getFileExtension(fileName, true),
uri: url,
uri: fromBuffer ? '_data_' : url,
directUrl: !userDirectUrl ? null : directUrl,
uriUser: directUrl,
created: new Date().toDateString(),

View File

@ -18,6 +18,8 @@
const path = require('path');
const fileSystem = require('fs');
const urllib = require('urllib');
const { emitWarning } = require('process');
const configServer = require('config').get('server');
const fileUtility = require('./fileUtility');
const documentService = require('./documentService');
@ -203,11 +205,12 @@ DocManager.prototype.getProtocol = function getProtocol() {
};
// get callback url
DocManager.prototype.getCallback = function getCallback(fileName) {
DocManager.prototype.getCallback = function getCallback(fileName, fromBuffer = false) {
const server = this.getServerUrl(true);
const hostAddress = this.curUserHostAddress();
const route = fromBuffer ? '/forcesave' : '/track';
// get callback handler
const handler = `/track?filename=${encodeURIComponent(fileName)}&useraddress=${encodeURIComponent(hostAddress)}`;
const handler = `${route}?filename=${encodeURIComponent(fileName)}&useraddress=${encodeURIComponent(hostAddress)}`;
return server + handler;
};
@ -269,6 +272,129 @@ DocManager.prototype.forcesavePath = function forcesavePath(fileName, userAddres
return directory;
};
DocManager.prototype.forcesaveFile = async function forcesaveFile(
data,
fileName,
downloadExt,
userAddress,
body = null,
newFileName = false,
isSubmitForm = false,
) {
let correctName = fileName;
let forcesavePath = '';
if (isSubmitForm) {
// new file
if (newFileName) {
correctName = this.getCorrectName(
`${fileUtility.getFileName(fileName, true)}-form${downloadExt}`,
userAddress,
);
} else {
const ext = fileUtility.getFileExtension(fileName);
correctName = this.getCorrectName(
`${fileUtility.getFileName(fileName, true)}-form${ext}`,
userAddress,
);
}
forcesavePath = this.storagePath(correctName, userAddress);
} else {
if (newFileName) {
correctName = this.getCorrectName(fileUtility.getFileName(
fileName,
true,
) + downloadExt, userAddress);
}
// create forcesave path if it doesn't exist
forcesavePath = this.forcesavePath(correctName, userAddress, false);
if (forcesavePath === '') {
forcesavePath = this.forcesavePath(correctName, userAddress, true);
}
}
fileSystem.writeFileSync(forcesavePath, data);
if (isSubmitForm) {
const uid = body.actions[0].userid;
this.saveFileData(correctName, uid, 'Filling Form', userAddress);
const { formsdataurl } = body;
if (formsdataurl) {
const formsdataName = this.getCorrectName(
`${fileUtility.getFileName(correctName, true)}.txt`,
userAddress,
);
// get the path to the file with forms data
const formsdataPath = this.storagePath(formsdataName, userAddress);
const formsdata = await urllib.request(formsdataurl, { method: 'GET' });
const statusFormsdata = formsdata.status;
const dataFormsdata = formsdata.data;
if (statusFormsdata === 200) {
fileSystem.writeFileSync(formsdataPath, dataFormsdata); // write the forms data
} else {
emitWarning(`Document editing service returned status: ${statusFormsdata}`);
}
} else {
emitWarning('Document editing service do not returned formsdataurl');
}
}
};
DocManager.prototype.saveFile = async function saveFile(fileName, newFileName, userAddress, body, data = null) {
const storagePath = this.storagePath(newFileName, userAddress);
let historyPath = this.historyPath(newFileName, userAddress); // get the path to the history data
if (historyPath === '') { // if the history path doesn't exist
historyPath = this.historyPath(newFileName, userAddress, true); // create it
this.createDirectory(historyPath); // and create a directory for the history data
}
const countVersion = this.countVersion(historyPath); // get the next file version number
const version = countVersion + 1;
// get the path to the specified file version
const versionPath = this.versionPath(newFileName, userAddress, version);
this.createDirectory(versionPath); // create a directory to the specified file version
const downloadZip = body.changesurl;
if (downloadZip) {
// get the path to the file with document versions differences
const pathChanges = this.diffPath(newFileName, userAddress, version);
const zip = await urllib.request(downloadZip, { method: 'GET' });
const statusZip = zip.status;
const dataZip = zip.data;
if (statusZip === 200) {
fileSystem.writeFileSync(pathChanges, dataZip); // write the document version differences to the archive
} else {
emitWarning(`Document editing service returned status: ${statusZip}`);
}
}
const changeshistory = body.changeshistory || JSON.stringify(body.history);
if (changeshistory) {
// get the path to the file with document changes
const pathChangesJson = this.changesPath(newFileName, userAddress, version);
fileSystem.writeFileSync(pathChangesJson, changeshistory); // and write this data to the path in json format
}
const pathKey = this.keyPath(newFileName, userAddress, version); // get the path to the key.txt file
fileSystem.writeFileSync(pathKey, body.key); // write the key value to the key.txt file
// get the path to the previous file version
const pathPrev = path.join(versionPath, `prev${fileUtility.getFileExtension(fileName)}`);
// and write it to the current path
fileSystem.renameSync(this.storagePath(fileName, userAddress), pathPrev);
// get the path to the forcesaved file
const forcesavePath = this.forcesavePath(newFileName, userAddress, false);
if (forcesavePath !== '') { // if this path is not empty
if (data === null) fileSystem.writeFileSync(storagePath, fileSystem.readFileSync(forcesavePath));
fileSystem.unlinkSync(forcesavePath); // remove it
}
if (data !== null) fileSystem.writeFileSync(storagePath, data);
};
// create the path to the file history
DocManager.prototype.historyPath = function historyPath(fileName, userAddress, create) {
let directory = this.storageRootPath(userAddress);

View File

@ -77,8 +77,29 @@
var onAppReady = function () { // the application is loaded into the browser
innerAlert("Document editor ready");
if (config.document.url === "_data_") {
let xhr = new XMLHttpRequest();
xhr.open("GET", "download?fileName=" + encodeURIComponent(config.document.title));
xhr.responseType = "arraybuffer";
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
docEditor.openDocument(new Uint8Array(xhr.response));
} else {
innerAlert("Failed to download document");
}
};
};
};
var onSaveDocument = function (event) {
let xhr = new XMLHttpRequest();
xhr.open("POST", "<%- bufferCallback %>");
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.send(event.data);
}
var onDocumentStateChange = function (event) { // the document is modified
var title = document.title.replace(/^\*/g, "");
document.title = (event.data ? "*" : "") + title;
@ -476,6 +497,10 @@
}
}
if (config.document.url === "_data_") {
config.events.onSaveDocument = onSaveDocument;
}
try {
var oformParam = new URL(window.location).searchParams.get("oform");
} catch (e) {}

View File

@ -111,11 +111,19 @@
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox collectable" name="directUrl" />Try opening on client
<input id="directUrl" type="checkbox" class="checkbox collectable" name="directUrl" />Opening direct link
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server. Open each file in only one way." src="images/info.svg" />
</label>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="fromBuffer" type="checkbox" class="checkbox collectable" name="fromBuffer" />Opening on client
<img id="fromBufferInfo" class="info info-tooltip" data-id="fromBufferInfo" data-tooltip="Download the file and transfer it to the editor on the client without requests from the document server." src="images/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -4,7 +4,7 @@
"firebase/php-jwt": "^6.10",
"laravel/framework": "^11.0",
"laravel/tinker": "^2.9",
"onlyoffice/docs-integration-sdk": "1.4"
"onlyoffice/docs-integration-sdk": "1.3.1"
},
"require-dev": {
"fakerphp/faker": "^1.23",

View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5a8d8cb88dd932786c6c5094f0163298",
"content-hash": "02a16d8e4ae3a9bbece00d8763b94b76",
"packages": [
{
"name": "brick/math",
@ -915,16 +915,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "2.9.0",
"version": "2.8.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884"
"reference": "21dc724a0583619cd1652f673303492272778051"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884",
"reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
"reference": "21dc724a0583619cd1652f673303492272778051",
"shasum": ""
},
"require": {
@ -940,7 +940,6 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"jshttp/mime-db": "1.54.0.1",
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
},
"suggest": {
@ -1012,7 +1011,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.9.0"
"source": "https://github.com/guzzle/psr7/tree/2.8.0"
},
"funding": [
{
@ -1028,7 +1027,7 @@
"type": "tidelift"
}
],
"time": "2026-03-10T16:41:02+00:00"
"time": "2025-08-23T21:21:41+00:00"
},
{
"name": "guzzlehttp/uri-template",
@ -1118,16 +1117,16 @@
},
{
"name": "laravel/framework",
"version": "v11.50.0",
"version": "v11.48.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "c761f591209b45f56c1317ecbff0b04c89cf7ba2"
"reference": "5b23ab29087dbcb13077e5c049c431ec4b82f236"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/c761f591209b45f56c1317ecbff0b04c89cf7ba2",
"reference": "c761f591209b45f56c1317ecbff0b04c89cf7ba2",
"url": "https://api.github.com/repos/laravel/framework/zipball/5b23ab29087dbcb13077e5c049c431ec4b82f236",
"reference": "5b23ab29087dbcb13077e5c049c431ec4b82f236",
"shasum": ""
},
"require": {
@ -1235,10 +1234,10 @@
"league/flysystem-read-only": "^3.25.1",
"league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10",
"orchestra/testbench-core": "^9.18.0",
"orchestra/testbench-core": "^9.16.1",
"pda/pheanstalk": "^5.0.6",
"php-http/discovery": "^1.15",
"phpstan/phpstan": "2.1.41",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^10.5.35|^11.3.6|^12.0.1",
"predis/predis": "^2.3",
"resend/resend-php": "^0.10.0",
@ -1329,20 +1328,20 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2026-03-17T19:35:22+00:00"
"time": "2026-01-20T15:26:20+00:00"
},
{
"name": "laravel/prompts",
"version": "v0.3.15",
"version": "v0.3.13",
"source": {
"type": "git",
"url": "https://github.com/laravel/prompts.git",
"reference": "4bb8107ec97651fd3f17f897d6489dbc4d8fb999"
"reference": "ed8c466571b37e977532fb2fd3c272c784d7050d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/4bb8107ec97651fd3f17f897d6489dbc4d8fb999",
"reference": "4bb8107ec97651fd3f17f897d6489dbc4d8fb999",
"url": "https://api.github.com/repos/laravel/prompts/zipball/ed8c466571b37e977532fb2fd3c272c784d7050d",
"reference": "ed8c466571b37e977532fb2fd3c272c784d7050d",
"shasum": ""
},
"require": {
@ -1386,9 +1385,9 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": {
"issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.3.15"
"source": "https://github.com/laravel/prompts/tree/v0.3.13"
},
"time": "2026-03-17T13:45:17+00:00"
"time": "2026-02-06T12:17:10+00:00"
},
{
"name": "laravel/serializable-closure",
@ -1896,20 +1895,20 @@
},
{
"name": "league/uri",
"version": "7.8.1",
"version": "7.8.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri.git",
"reference": "08cf38e3924d4f56238125547b5720496fac8fd4"
"reference": "4436c6ec8d458e4244448b069cc572d088230b76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4",
"reference": "08cf38e3924d4f56238125547b5720496fac8fd4",
"url": "https://api.github.com/repos/thephpleague/uri/zipball/4436c6ec8d458e4244448b069cc572d088230b76",
"reference": "4436c6ec8d458e4244448b069cc572d088230b76",
"shasum": ""
},
"require": {
"league/uri-interfaces": "^7.8.1",
"league/uri-interfaces": "^7.8",
"php": "^8.1",
"psr/http-factory": "^1"
},
@ -1982,7 +1981,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
"source": "https://github.com/thephpleague/uri/tree/7.8.1"
"source": "https://github.com/thephpleague/uri/tree/7.8.0"
},
"funding": [
{
@ -1990,20 +1989,20 @@
"type": "github"
}
],
"time": "2026-03-15T20:22:25+00:00"
"time": "2026-01-14T17:24:56+00:00"
},
{
"name": "league/uri-interfaces",
"version": "7.8.1",
"version": "7.8.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri-interfaces.git",
"reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928"
"reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928",
"reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928",
"url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c5c5cd056110fc8afaba29fa6b72a43ced42acd4",
"reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4",
"shasum": ""
},
"require": {
@ -2066,7 +2065,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
"source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1"
"source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.0"
},
"funding": [
{
@ -2074,7 +2073,7 @@
"type": "github"
}
],
"time": "2026-03-08T20:05:35+00:00"
"time": "2026-01-15T06:54:53+00:00"
},
{
"name": "monolog/monolog",
@ -2181,16 +2180,16 @@
},
{
"name": "nesbot/carbon",
"version": "3.11.3",
"version": "3.11.1",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon.git",
"reference": "6a7e652845bb018c668220c2a545aded8594fbbf"
"reference": "f438fcc98f92babee98381d399c65336f3a3827f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6a7e652845bb018c668220c2a545aded8594fbbf",
"reference": "6a7e652845bb018c668220c2a545aded8594fbbf",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/f438fcc98f92babee98381d399c65336f3a3827f",
"reference": "f438fcc98f92babee98381d399c65336f3a3827f",
"shasum": ""
},
"require": {
@ -2282,7 +2281,7 @@
"type": "tidelift"
}
],
"time": "2026-03-11T17:23:39+00:00"
"time": "2026-01-29T09:26:29+00:00"
},
{
"name": "nette/schema",
@ -2589,16 +2588,16 @@
},
{
"name": "onlyoffice/docs-integration-sdk",
"version": "1.4.0",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/ONLYOFFICE/docs-integration-sdk-php.git",
"reference": "94bac87085bd6957c5f3c0fed8f134e4c2b1b691"
"reference": "4d9aac28f0ecda6a83797fab1240204ca5128e6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ONLYOFFICE/docs-integration-sdk-php/zipball/94bac87085bd6957c5f3c0fed8f134e4c2b1b691",
"reference": "94bac87085bd6957c5f3c0fed8f134e4c2b1b691",
"url": "https://api.github.com/repos/ONLYOFFICE/docs-integration-sdk-php/zipball/4d9aac28f0ecda6a83797fab1240204ca5128e6e",
"reference": "4d9aac28f0ecda6a83797fab1240204ca5128e6e",
"shasum": ""
},
"require": {
@ -2641,7 +2640,7 @@
"issues": "https://github.com/ONLYOFFICE/docs-integration-sdk-php/issues",
"source": "https://github.com/ONLYOFFICE/docs-integration-sdk-php"
},
"time": "2026-03-17T11:38:56+00:00"
"time": "2026-01-26T13:00:36+00:00"
},
{
"name": "phpoption/phpoption",
@ -3132,16 +3131,16 @@
},
{
"name": "psy/psysh",
"version": "v0.12.21",
"version": "v0.12.20",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97"
"reference": "19678eb6b952a03b8a1d96ecee9edba518bb0373"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/4821fab5b7cd8c49a673a9fd5754dc9162bb9e97",
"reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/19678eb6b952a03b8a1d96ecee9edba518bb0373",
"reference": "19678eb6b952a03b8a1d96ecee9edba518bb0373",
"shasum": ""
},
"require": {
@ -3205,9 +3204,9 @@
],
"support": {
"issues": "https://github.com/bobthecow/psysh/issues",
"source": "https://github.com/bobthecow/psysh/tree/v0.12.21"
"source": "https://github.com/bobthecow/psysh/tree/v0.12.20"
},
"time": "2026-03-06T21:21:28+00:00"
"time": "2026-02-11T15:05:28+00:00"
},
{
"name": "ralouphie/getallheaders",
@ -3487,16 +3486,16 @@
},
{
"name": "symfony/console",
"version": "v7.4.7",
"version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d"
"reference": "6d643a93b47398599124022eb24d97c153c12f27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/e1e6770440fb9c9b0cf725f81d1361ad1835329d",
"reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d",
"url": "https://api.github.com/repos/symfony/console/zipball/6d643a93b47398599124022eb24d97c153c12f27",
"reference": "6d643a93b47398599124022eb24d97c153c12f27",
"shasum": ""
},
"require": {
@ -3561,7 +3560,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.4.7"
"source": "https://github.com/symfony/console/tree/v7.4.6"
},
"funding": [
{
@ -3581,7 +3580,7 @@
"type": "tidelift"
}
],
"time": "2026-03-06T14:06:20+00:00"
"time": "2026-02-25T17:02:47+00:00"
},
{
"name": "symfony/css-selector",
@ -4032,16 +4031,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v7.4.7",
"version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "f94b3e7b7dafd40e666f0c9ff2084133bae41e81"
"reference": "fd97d5e926e988a363cef56fbbf88c5c528e9065"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/f94b3e7b7dafd40e666f0c9ff2084133bae41e81",
"reference": "f94b3e7b7dafd40e666f0c9ff2084133bae41e81",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/fd97d5e926e988a363cef56fbbf88c5c528e9065",
"reference": "fd97d5e926e988a363cef56fbbf88c5c528e9065",
"shasum": ""
},
"require": {
@ -4090,7 +4089,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.4.7"
"source": "https://github.com/symfony/http-foundation/tree/v7.4.6"
},
"funding": [
{
@ -4110,20 +4109,20 @@
"type": "tidelift"
}
],
"time": "2026-03-06T13:15:18+00:00"
"time": "2026-02-21T16:25:55+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v7.4.7",
"version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "3b3fcf386c809be990c922e10e4c620d6367cab1"
"reference": "002ac0cf4cd972a7fd0912dcd513a95e8a81ce83"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/3b3fcf386c809be990c922e10e4c620d6367cab1",
"reference": "3b3fcf386c809be990c922e10e4c620d6367cab1",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/002ac0cf4cd972a7fd0912dcd513a95e8a81ce83",
"reference": "002ac0cf4cd972a7fd0912dcd513a95e8a81ce83",
"shasum": ""
},
"require": {
@ -4209,7 +4208,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-kernel/tree/v7.4.7"
"source": "https://github.com/symfony/http-kernel/tree/v7.4.6"
},
"funding": [
{
@ -4229,7 +4228,7 @@
"type": "tidelift"
}
],
"time": "2026-03-06T16:33:18+00:00"
"time": "2026-02-26T08:30:57+00:00"
},
{
"name": "symfony/mailer",
@ -4317,16 +4316,16 @@
},
{
"name": "symfony/mime",
"version": "v7.4.7",
"version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1"
"reference": "9fc881d95feae4c6c48678cb6372bd8a7ba04f5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/da5ab4fde3f6c88ab06e96185b9922f48b677cd1",
"reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1",
"url": "https://api.github.com/repos/symfony/mime/zipball/9fc881d95feae4c6c48678cb6372bd8a7ba04f5f",
"reference": "9fc881d95feae4c6c48678cb6372bd8a7ba04f5f",
"shasum": ""
},
"require": {
@ -4382,7 +4381,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v7.4.7"
"source": "https://github.com/symfony/mime/tree/v7.4.6"
},
"funding": [
{
@ -4402,7 +4401,7 @@
"type": "tidelift"
}
],
"time": "2026-03-05T15:24:09+00:00"
"time": "2026-02-05T15:57:06+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -6230,16 +6229,16 @@
},
{
"name": "laravel/pint",
"version": "v1.29.0",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "bdec963f53172c5e36330f3a400604c69bf02d39"
"reference": "1feae84bf9c1649d99ba8f7b8193bf0f09f04cc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/bdec963f53172c5e36330f3a400604c69bf02d39",
"reference": "bdec963f53172c5e36330f3a400604c69bf02d39",
"url": "https://api.github.com/repos/laravel/pint/zipball/1feae84bf9c1649d99ba8f7b8193bf0f09f04cc9",
"reference": "1feae84bf9c1649d99ba8f7b8193bf0f09f04cc9",
"shasum": ""
},
"require": {
@ -6256,8 +6255,8 @@
"laravel-zero/framework": "^12.0.5",
"mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^2.4.0",
"pestphp/pest": "^3.8.6",
"shipfastlabs/agent-detector": "^1.1.0"
"pestphp/pest": "^3.8.5",
"shipfastlabs/agent-detector": "^1.0.2"
},
"bin": [
"builds/pint"
@ -6294,20 +6293,20 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2026-03-12T15:51:39+00:00"
"time": "2026-03-10T20:37:18+00:00"
},
{
"name": "laravel/sail",
"version": "v1.54.0",
"version": "v1.53.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/sail.git",
"reference": "bcc5e06f1a79d806d880a4b027964d2aa5872b07"
"reference": "e340eaa2bea9b99192570c48ed837155dbf24fbb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sail/zipball/bcc5e06f1a79d806d880a4b027964d2aa5872b07",
"reference": "bcc5e06f1a79d806d880a4b027964d2aa5872b07",
"url": "https://api.github.com/repos/laravel/sail/zipball/e340eaa2bea9b99192570c48ed837155dbf24fbb",
"reference": "e340eaa2bea9b99192570c48ed837155dbf24fbb",
"shasum": ""
},
"require": {
@ -6357,7 +6356,7 @@
"issues": "https://github.com/laravel/sail/issues",
"source": "https://github.com/laravel/sail"
},
"time": "2026-03-11T14:10:52+00:00"
"time": "2026-02-06T12:16:02+00:00"
},
{
"name": "mockery/mockery",
@ -8161,16 +8160,16 @@
},
{
"name": "spatie/backtrace",
"version": "1.8.2",
"version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/backtrace.git",
"reference": "8ffe78be5ed355b5009e3dd989d183433e9a5adc"
"reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/backtrace/zipball/8ffe78be5ed355b5009e3dd989d183433e9a5adc",
"reference": "8ffe78be5ed355b5009e3dd989d183433e9a5adc",
"url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110",
"reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110",
"shasum": ""
},
"require": {
@ -8181,7 +8180,7 @@
"laravel/serializable-closure": "^1.3 || ^2.0",
"phpunit/phpunit": "^9.3 || ^11.4.3",
"spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6",
"symfony/var-dumper": "^5.1|^6.0|^7.0|^8.0"
"symfony/var-dumper": "^5.1 || ^6.0 || ^7.0"
},
"type": "library",
"autoload": {
@ -8209,7 +8208,7 @@
],
"support": {
"issues": "https://github.com/spatie/backtrace/issues",
"source": "https://github.com/spatie/backtrace/tree/1.8.2"
"source": "https://github.com/spatie/backtrace/tree/1.8.1"
},
"funding": [
{
@ -8221,7 +8220,7 @@
"type": "other"
}
],
"time": "2026-03-11T13:48:28+00:00"
"time": "2025-08-26T08:22:30+00:00"
},
{
"name": "spatie/error-solutions",
@ -8299,26 +8298,26 @@
},
{
"name": "spatie/flare-client-php",
"version": "1.11.0",
"version": "1.10.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/flare-client-php.git",
"reference": "fb3ffb946675dba811fbde9122224db2f84daca9"
"reference": "bf1716eb98bd689451b071548ae9e70738dce62f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/fb3ffb946675dba811fbde9122224db2f84daca9",
"reference": "fb3ffb946675dba811fbde9122224db2f84daca9",
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/bf1716eb98bd689451b071548ae9e70738dce62f",
"reference": "bf1716eb98bd689451b071548ae9e70738dce62f",
"shasum": ""
},
"require": {
"illuminate/pipeline": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
"illuminate/pipeline": "^8.0|^9.0|^10.0|^11.0|^12.0",
"php": "^8.0",
"spatie/backtrace": "^1.6.1",
"symfony/http-foundation": "^5.2|^6.0|^7.0|^8.0",
"symfony/mime": "^5.2|^6.0|^7.0|^8.0",
"symfony/process": "^5.2|^6.0|^7.0|^8.0",
"symfony/var-dumper": "^5.2|^6.0|^7.0|^8.0"
"symfony/http-foundation": "^5.2|^6.0|^7.0",
"symfony/mime": "^5.2|^6.0|^7.0",
"symfony/process": "^5.2|^6.0|^7.0",
"symfony/var-dumper": "^5.2|^6.0|^7.0"
},
"require-dev": {
"dms/phpunit-arraysubset-asserts": "^0.5.0",
@ -8356,7 +8355,7 @@
],
"support": {
"issues": "https://github.com/spatie/flare-client-php/issues",
"source": "https://github.com/spatie/flare-client-php/tree/1.11.0"
"source": "https://github.com/spatie/flare-client-php/tree/1.10.1"
},
"funding": [
{
@ -8364,44 +8363,41 @@
"type": "github"
}
],
"time": "2026-03-17T08:06:16+00:00"
"time": "2025-02-14T13:42:06+00:00"
},
{
"name": "spatie/ignition",
"version": "1.16.0",
"version": "1.15.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/ignition.git",
"reference": "b59385bb7aa24dae81bcc15850ebecfda7b40838"
"reference": "31f314153020aee5af3537e507fef892ffbf8c85"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/ignition/zipball/b59385bb7aa24dae81bcc15850ebecfda7b40838",
"reference": "b59385bb7aa24dae81bcc15850ebecfda7b40838",
"url": "https://api.github.com/repos/spatie/ignition/zipball/31f314153020aee5af3537e507fef892ffbf8c85",
"reference": "31f314153020aee5af3537e507fef892ffbf8c85",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"php": "^8.0",
"spatie/backtrace": "^1.7.1",
"spatie/error-solutions": "^1.1.2",
"spatie/flare-client-php": "^1.9",
"symfony/console": "^5.4.42|^6.0|^7.0|^8.0",
"symfony/http-foundation": "^5.4.42|^6.0|^7.0|^8.0",
"symfony/mime": "^5.4.42|^6.0|^7.0|^8.0",
"symfony/var-dumper": "^5.4.42|^6.0|^7.0|^8.0"
"spatie/error-solutions": "^1.0",
"spatie/flare-client-php": "^1.7",
"symfony/console": "^5.4|^6.0|^7.0",
"symfony/var-dumper": "^5.4|^6.0|^7.0"
},
"require-dev": {
"illuminate/cache": "^9.52|^10.0|^11.0|^12.0|^13.0",
"illuminate/cache": "^9.52|^10.0|^11.0|^12.0",
"mockery/mockery": "^1.4",
"pestphp/pest": "^1.20|^2.0|^3.0",
"pestphp/pest": "^1.20|^2.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
"psr/simple-cache-implementation": "*",
"symfony/cache": "^5.4.38|^6.0|^7.0|^8.0",
"symfony/process": "^5.4.35|^6.0|^7.0|^8.0",
"symfony/cache": "^5.4|^6.0|^7.0",
"symfony/process": "^5.4|^6.0|^7.0",
"vlucas/phpdotenv": "^5.5"
},
"suggest": {
@ -8450,20 +8446,20 @@
"type": "github"
}
],
"time": "2026-03-17T10:51:08+00:00"
"time": "2025-02-21T14:31:39+00:00"
},
{
"name": "spatie/laravel-ignition",
"version": "2.12.0",
"version": "2.11.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-ignition.git",
"reference": "45b3b6e1e73fc161cba2149972698644b99594ee"
"reference": "11f38d1ff7abc583a61c96bf3c1b03610a69cccd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/45b3b6e1e73fc161cba2149972698644b99594ee",
"reference": "45b3b6e1e73fc161cba2149972698644b99594ee",
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/11f38d1ff7abc583a61c96bf3c1b03610a69cccd",
"reference": "11f38d1ff7abc583a61c96bf3c1b03610a69cccd",
"shasum": ""
},
"require": {
@ -8473,7 +8469,7 @@
"illuminate/support": "^11.0|^12.0|^13.0",
"nesbot/carbon": "^2.72|^3.0",
"php": "^8.2",
"spatie/ignition": "^1.16",
"spatie/ignition": "^1.15.1",
"symfony/console": "^7.4|^8.0",
"symfony/var-dumper": "^7.4|^8.0"
},
@ -8542,7 +8538,7 @@
"type": "github"
}
],
"time": "2026-03-17T12:20:04+00:00"
"time": "2026-02-22T19:14:05+00:00"
},
{
"name": "staabm/side-effects-detector",
@ -8731,6 +8727,6 @@
"platform": {
"php": "^8.2"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"platform-dev": {},
"plugin-api-version": "2.9.0"
}