chore: remove trailing commas
This commit is contained in:
parent
13825ddae6
commit
90001c2df5
|
@ -175,7 +175,11 @@
|
|||
"import/no-extraneous-dependencies": "off",
|
||||
"no-restricted-syntax": "off",
|
||||
"no-continue": "off",
|
||||
"no-await-in-loop": "off"
|
||||
"no-await-in-loop": "off",
|
||||
"comma-dangle": [
|
||||
"error",
|
||||
"never"
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
|
|
|
@ -15,7 +15,7 @@ exports.seed = async (db) => {
|
|||
createdAt: now,
|
||||
editedAt: now,
|
||||
enabled: true,
|
||||
isAdmin: true,
|
||||
isAdmin: true
|
||||
});
|
||||
console.log();
|
||||
console.log('=========================================================');
|
||||
|
|
|
@ -4,31 +4,71 @@
|
|||
const nodePath = require('path');
|
||||
const moment = require('moment');
|
||||
const jetpack = require('fs-jetpack');
|
||||
const { path } = require('fs-jetpack');
|
||||
const sharp = require('sharp');
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
|
||||
const imageExtensions = ['.jpg', '.jpeg', '.bmp', '.gif', '.png', '.webp'];
|
||||
const videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
|
||||
|
||||
const generateThumbnailForImage = async (filename, output) => {
|
||||
try {
|
||||
const file = await jetpack.readAsync(nodePath.join(__dirname, '../../uploads', filename), 'buffer');
|
||||
await sharp(file)
|
||||
.resize(64, 64)
|
||||
.toFormat('webp')
|
||||
.toFile(nodePath.join(__dirname, '../../uploads/thumbs/square', output));
|
||||
await sharp(file)
|
||||
.resize(225, null)
|
||||
.toFormat('webp')
|
||||
.toFile(nodePath.join(__dirname, '../../uploads/thumbs', output));
|
||||
console.log('finished', filename);
|
||||
} catch (error) {
|
||||
console.log('error', filename);
|
||||
}
|
||||
};
|
||||
|
||||
const generateThumbnailForVideo = (filename) => {
|
||||
try {
|
||||
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
||||
.thumbnail({
|
||||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: nodePath.join(__dirname, '../../uploads/thumbs/square'),
|
||||
size: '64x64'
|
||||
})
|
||||
.on('error', (error) => console.error(error.message));
|
||||
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
||||
.thumbnail({
|
||||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: nodePath.join(__dirname, '../../uploads/thumbs'),
|
||||
size: '150x?'
|
||||
})
|
||||
.on('error', (error) => console.error(error.message));
|
||||
console.log('finished', filename);
|
||||
} catch (error) {
|
||||
console.log('error', filename);
|
||||
}
|
||||
};
|
||||
|
||||
const oldDb = require('knex')({
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: nodePath.join(__dirname, '..', '..', 'db'),
|
||||
filename: nodePath.join(__dirname, '../../', 'db')
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
useNullAsDefault: true
|
||||
});
|
||||
|
||||
const newDb = require('knex')({
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: nodePath.join(__dirname, '..', '..', 'database.sqlite'),
|
||||
filename: nodePath.join(__dirname, '../../', 'database.sqlite')
|
||||
},
|
||||
postProcessResponse: (result) => {
|
||||
const booleanFields = [
|
||||
'enabled',
|
||||
'enableDownload',
|
||||
'isAdmin',
|
||||
'isAdmin'
|
||||
];
|
||||
|
||||
const processResponse = (row) => {
|
||||
|
@ -45,15 +85,15 @@ const newDb = require('knex')({
|
|||
if (typeof result === 'object') return processResponse(result);
|
||||
return result;
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
useNullAsDefault: true
|
||||
});
|
||||
|
||||
const start = async () => {
|
||||
console.log('Starting migration, this may take a few minutes...'); // Because I half assed it
|
||||
console.log('Please do NOT kill the process. Wait for it to finish.');
|
||||
|
||||
await jetpack.removeAsync(nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs'));
|
||||
await jetpack.dirAsync(nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs', 'square'));
|
||||
await jetpack.removeAsync(nodePath.join(__dirname, '../../uploads/thumbs'));
|
||||
await jetpack.dirAsync(nodePath.join(__dirname, '../../uploads/thumbs/square'));
|
||||
console.log('Finished deleting old thumbnails to create new ones');
|
||||
|
||||
const users = await oldDb.table('users').where('username', '<>', 'root');
|
||||
|
@ -69,7 +109,7 @@ const start = async () => {
|
|||
passwordEditedAt: now,
|
||||
apiKeyEditedAt: now,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
};
|
||||
await newDb.table('users').insert(userToInsert);
|
||||
}
|
||||
|
@ -85,7 +125,7 @@ const start = async () => {
|
|||
name: album.name,
|
||||
zippedAt: album.zipGeneratedAt ? moment.unix(album.zipGeneratedAt).toDate() : null,
|
||||
createdAt: moment.unix(album.timestamp).toDate(),
|
||||
editedAt: moment.unix(album.editedAt).toDate(),
|
||||
editedAt: moment.unix(album.editedAt).toDate()
|
||||
};
|
||||
const linkToInsert = {
|
||||
userId: album.userid,
|
||||
|
@ -95,13 +135,13 @@ const start = async () => {
|
|||
enabled: true,
|
||||
enableDownload: true,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
};
|
||||
await newDb.table('albums').insert(albumToInsert);
|
||||
const insertedId = await newDb.table('links').insert(linkToInsert);
|
||||
await newDb.table('albumsLinks').insert({
|
||||
albumId: album.id,
|
||||
linkId: insertedId[0],
|
||||
linkId: insertedId[0]
|
||||
});
|
||||
}
|
||||
console.log('Finished migrating albums...');
|
||||
|
@ -120,16 +160,16 @@ const start = async () => {
|
|||
hash: file.hash,
|
||||
ip: file.ip,
|
||||
createdAt: moment.unix(file.timestamp).toDate(),
|
||||
editedAt: moment.unix(file.timestamp).toDate(),
|
||||
editedAt: moment.unix(file.timestamp).toDate()
|
||||
};
|
||||
filesToInsert.push(fileToInsert);
|
||||
albumsFilesToInsert.push({
|
||||
albumId: file.albumid,
|
||||
fileId: file.id,
|
||||
fileId: file.id
|
||||
});
|
||||
|
||||
const filename = file.name;
|
||||
if (!jetpack.exists(nodePath.join(__dirname, '..', '..', 'uploads', filename))) continue;
|
||||
if (!jetpack.exists(nodePath.join(__dirname, '../../uploads', filename))) continue;
|
||||
const ext = nodePath.extname(filename).toLowerCase();
|
||||
const output = `${filename.slice(0, -ext.length)}.webp`;
|
||||
if (imageExtensions.includes(ext)) await generateThumbnailForImage(filename, output);
|
||||
|
@ -143,45 +183,4 @@ const start = async () => {
|
|||
process.exit(0);
|
||||
};
|
||||
|
||||
const generateThumbnailForImage = async (filename, output) => {
|
||||
try {
|
||||
const file = await jetpack.readAsync(nodePath.join(__dirname, '..', '..', 'uploads', filename), 'buffer');
|
||||
await sharp(file)
|
||||
.resize(64, 64)
|
||||
.toFormat('webp')
|
||||
.toFile(nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs', 'square', output));
|
||||
await sharp(file)
|
||||
.resize(225, null)
|
||||
.toFormat('webp')
|
||||
.toFile(nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs', output));
|
||||
console.log('finished', filename);
|
||||
} catch (error) {
|
||||
console.log('error', filename);
|
||||
}
|
||||
};
|
||||
|
||||
const generateThumbnailForVideo = filename => {
|
||||
try {
|
||||
ffmpeg(nodePath.join(__dirname, '..', '..', 'uploads', filename))
|
||||
.thumbnail({
|
||||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs', 'square'),
|
||||
size: '64x64'
|
||||
})
|
||||
.on('error', error => console.error(error.message));
|
||||
ffmpeg(nodePath.join(__dirname, '..', '..', 'uploads', filename))
|
||||
.thumbnail({
|
||||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: nodePath.join(__dirname, '..', '..', 'uploads', 'thumbs'),
|
||||
size: '150x?'
|
||||
})
|
||||
.on('error', error => console.error(error.message));
|
||||
console.log('finished', filename);
|
||||
} catch (error) {
|
||||
console.log('error', filename);
|
||||
}
|
||||
};
|
||||
|
||||
start();
|
||||
|
|
|
@ -6,7 +6,7 @@ const path = require('path');
|
|||
const ThumbUtil = require('./utils/ThumbUtil');
|
||||
|
||||
const start = async () => {
|
||||
const files = fs.readdirSync(path.join(__dirname, '..', '..', process.env.UPLOAD_FOLDER));
|
||||
const files = fs.readdirSync(path.join(__dirname, '../../', process.env.UPLOAD_FOLDER));
|
||||
for (const fileName of files) {
|
||||
console.log(`Generating thumb for '${fileName}`);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
|
|
|
@ -17,7 +17,7 @@ class banIP extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully banned the ip',
|
||||
message: 'Successfully banned the ip'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class filesGET extends Route {
|
|||
return res.json({
|
||||
message: 'Successfully retrieved file',
|
||||
file,
|
||||
user,
|
||||
user
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class unBanIP extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully unbanned the ip',
|
||||
message: 'Successfully unbanned the ip'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class userDemote extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully demoted user',
|
||||
message: 'Successfully demoted user'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class userDisable extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully disabled user',
|
||||
message: 'Successfully disabled user'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class userEnable extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully enabled user',
|
||||
message: 'Successfully enabled user'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class usersGET extends Route {
|
|||
return res.json({
|
||||
message: 'Successfully retrieved user',
|
||||
user,
|
||||
files,
|
||||
files
|
||||
});
|
||||
} catch (error) {
|
||||
return super.error(res, error);
|
||||
|
|
|
@ -20,7 +20,7 @@ class userPromote extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully promoted user',
|
||||
message: 'Successfully promoted user'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ class userDemote extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully deleted the user\'s files',
|
||||
message: 'Successfully deleted the user\'s files'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class usersGET extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully retrieved users',
|
||||
users,
|
||||
users
|
||||
});
|
||||
} catch (error) {
|
||||
return super.error(res, error);
|
||||
|
|
|
@ -50,7 +50,7 @@ class albumGET extends Route {
|
|||
message: 'Successfully retrieved album',
|
||||
name: album.name,
|
||||
files,
|
||||
count,
|
||||
count
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class albumGET extends Route {
|
|||
message: 'Successfully retrieved files',
|
||||
name: album.name,
|
||||
downloadEnabled: link.enableDownload,
|
||||
files,
|
||||
files
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class albumPOST extends Route {
|
|||
name,
|
||||
userId: user.id,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
};
|
||||
|
||||
const dbRes = await db.table('albums').insert(insertObj);
|
||||
|
|
|
@ -21,7 +21,7 @@ class albumGET extends Route {
|
|||
.where({
|
||||
identifier,
|
||||
enabled: true,
|
||||
enableDownload: true,
|
||||
enableDownload: true
|
||||
})
|
||||
.first();
|
||||
if (!link) return res.status(400).json({ message: 'The supplied identifier could not be found' });
|
||||
|
@ -38,7 +38,7 @@ class albumGET extends Route {
|
|||
If the date when the album was zipped is greater than the album's last edit, we just send the zip to the user
|
||||
*/
|
||||
if (album.zippedAt > album.editedAt) {
|
||||
const filePath = path.join(__dirname, '..', '..', '..', '..', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
|
||||
const filePath = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
|
||||
const exists = await jetpack.existsAsync(filePath);
|
||||
/*
|
||||
Make sure the file exists just in case, and if not, continue to it's generation.
|
||||
|
@ -76,7 +76,7 @@ class albumGET extends Route {
|
|||
.where('id', link.albumId)
|
||||
.update('zippedAt', db.fn.now());
|
||||
|
||||
const filePath = path.join(__dirname, '..', '..', '..', '..', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
|
||||
const filePath = path.join(__dirname, '../../../../', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`);
|
||||
const fileName = `lolisafe-${identifier}.zip`;
|
||||
return res.download(filePath, fileName);
|
||||
} catch (error) {
|
||||
|
|
|
@ -46,7 +46,7 @@ class albumsGET extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully retrieved albums',
|
||||
albums,
|
||||
albums
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class albumsDropdownGET extends Route {
|
|||
.select('id', 'name');
|
||||
return res.json({
|
||||
message: 'Successfully retrieved albums',
|
||||
albums,
|
||||
albums
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class linkDELETE extends Route {
|
|||
}
|
||||
|
||||
return res.json({
|
||||
message: 'Successfully deleted link',
|
||||
message: 'Successfully deleted link'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class linkEditPOST extends Route {
|
|||
try {
|
||||
const updateObj = {
|
||||
enableDownload: enableDownload || false,
|
||||
expiresAt, // This one should be null if not supplied
|
||||
expiresAt // This one should be null if not supplied
|
||||
};
|
||||
await db
|
||||
.table('links')
|
||||
|
|
|
@ -61,13 +61,13 @@ class linkPOST extends Route {
|
|||
enabled: true,
|
||||
enableDownload: true,
|
||||
expiresAt: null,
|
||||
views: 0,
|
||||
views: 0
|
||||
};
|
||||
await db.table('links').insert(insertObj);
|
||||
|
||||
return res.json({
|
||||
message: 'The link was created successfully',
|
||||
data: insertObj,
|
||||
data: insertObj
|
||||
});
|
||||
} catch (error) {
|
||||
return super.error(res, error);
|
||||
|
|
|
@ -14,7 +14,7 @@ class linkPOST extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully retrieved links',
|
||||
links,
|
||||
links
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class loginPOST extends Route {
|
|||
const jwt = JWT.sign({
|
||||
iss: 'lolisafe',
|
||||
sub: user.id,
|
||||
iat: moment.utc().valueOf(),
|
||||
iat: moment.utc().valueOf()
|
||||
}, process.env.SECRET, { expiresIn: '30d' });
|
||||
|
||||
return res.json({
|
||||
|
@ -45,10 +45,10 @@ class loginPOST extends Route {
|
|||
id: user.id,
|
||||
username: user.username,
|
||||
apiKey: user.apiKey,
|
||||
isAdmin: user.isAdmin,
|
||||
isAdmin: user.isAdmin
|
||||
},
|
||||
token: jwt,
|
||||
apiKey: user.apiKey,
|
||||
apiKey: user.apiKey
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class registerPOST extends Route {
|
|||
createdAt: now,
|
||||
editedAt: now,
|
||||
enabled: true,
|
||||
isAdmin: false,
|
||||
isAdmin: false
|
||||
});
|
||||
return res.json({ message: 'The account was created successfully' });
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class albumAddPOST extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully added file to album',
|
||||
data: { fileId, album: { id: album.id, name: album.name } },
|
||||
data: { fileId, album: { id: album.id, name: album.name } }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class albumDelPOST extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully removed file from album',
|
||||
data: { fileId, album: { id: album.id, name: album.name } },
|
||||
data: { fileId, album: { id: album.id, name: album.name } }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class fileGET extends Route {
|
|||
message: 'Successfully retrieved file',
|
||||
file,
|
||||
albums,
|
||||
tags,
|
||||
tags
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class filesGET extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully retrieved file albums',
|
||||
albums,
|
||||
albums
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class filesGET extends Route {
|
|||
return res.json({
|
||||
message: 'Successfully retrieved files',
|
||||
files,
|
||||
count,
|
||||
count
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class tagAddBatchPOST extends Route {
|
|||
return res.json({
|
||||
message: 'Successfully added tags to file',
|
||||
data: { fileId, tags: addedTags },
|
||||
errors,
|
||||
errors
|
||||
});
|
||||
// eslint-disable-next-line consistent-return
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class tagAddPOST extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully added tag to file',
|
||||
data: { fileId, tag },
|
||||
data: { fileId, tag }
|
||||
});
|
||||
// eslint-disable-next-line consistent-return
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class tagDelPost extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully removed tag from file',
|
||||
data: { fileId, tag },
|
||||
data: { fileId, tag }
|
||||
});
|
||||
// eslint-disable-next-line consistent-return
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ const options = {
|
|||
keywords: ['album', 'tag', 'before', 'after', 'file'],
|
||||
offsets: false,
|
||||
alwaysArray: true,
|
||||
tokenize: true,
|
||||
tokenize: true
|
||||
};
|
||||
|
||||
class configGET extends Route {
|
||||
|
@ -55,7 +55,7 @@ class configGET extends Route {
|
|||
query,
|
||||
parsed,
|
||||
files,
|
||||
count,
|
||||
count
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ class configGET extends Route {
|
|||
generateThumbnails: process.env.GENERATE_THUMBNAILS === 'true',
|
||||
generateZips: process.env.GENERATE_ZIPS === 'true',
|
||||
publicMode: process.env.PUBLIC_MODE === 'true',
|
||||
enableAccounts: process.env.USER_ACCOUNTS === 'true',
|
||||
},
|
||||
enableAccounts: process.env.USER_ACCOUNTS === 'true'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class tagPOST extends Route {
|
|||
name,
|
||||
userId: user.id,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
};
|
||||
|
||||
const dbRes = await db.table('tags').insert(insertObj);
|
||||
|
|
|
@ -19,7 +19,7 @@ class tagsGET extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully retrieved tags',
|
||||
tags,
|
||||
tags
|
||||
});
|
||||
} catch (error) {
|
||||
return super.error(res, error);
|
||||
|
|
|
@ -8,7 +8,7 @@ class uploadPOST extends Route {
|
|||
constructor() {
|
||||
super('/upload/chunks', 'post', {
|
||||
bypassAuth: true,
|
||||
canApiKey: true,
|
||||
canApiKey: true
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class uploadPOST extends Route {
|
|||
// console.log('Files', req.body.files);
|
||||
const info = {
|
||||
size: req.body.files[0].size,
|
||||
url: `${process.env.DOMAIN}/`,
|
||||
url: `${process.env.DOMAIN}/`
|
||||
};
|
||||
|
||||
for (const chunk of req.body.files) {
|
||||
|
@ -56,7 +56,7 @@ class uploadPOST extends Route {
|
|||
|
||||
return res.status(201).send({
|
||||
message: 'Sucessfully merged the chunk(s).',
|
||||
...info,
|
||||
...info
|
||||
/*
|
||||
name: `${filename}${ext || ''}`,
|
||||
size: exists.size,
|
||||
|
|
|
@ -9,7 +9,7 @@ const upload = multer({
|
|||
storage: multer.memoryStorage(),
|
||||
limits: {
|
||||
fileSize: parseInt(process.env.MAX_SIZE, 10) * (1000 * 1000),
|
||||
files: 1,
|
||||
files: 1
|
||||
},
|
||||
fileFilter: (req, file, cb) =>
|
||||
// TODO: Enable blacklisting of files/extensions
|
||||
|
@ -21,7 +21,7 @@ const upload = multer({
|
|||
}
|
||||
*/
|
||||
cb(null, true)
|
||||
,
|
||||
|
||||
}).array('files[]');
|
||||
|
||||
/*
|
||||
|
@ -41,7 +41,7 @@ class uploadPOST extends Route {
|
|||
constructor() {
|
||||
super('/upload', 'post', {
|
||||
bypassAuth: true,
|
||||
canApiKey: true,
|
||||
canApiKey: true
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ class uploadPOST extends Route {
|
|||
name: filename,
|
||||
hash,
|
||||
size: file.buffer.length,
|
||||
url: filename,
|
||||
url: filename
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ class uploadPOST extends Route {
|
|||
uploadedFile = Util.constructFilePublicLink(uploadedFile);
|
||||
return res.status(201).send({
|
||||
message: 'Sucessfully uploaded the file.',
|
||||
...uploadedFile,
|
||||
...uploadedFile
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ class uploadPOST extends Route {
|
|||
size: exists.size,
|
||||
url: `${process.env.DOMAIN}/${exists.name}`,
|
||||
deleteUrl: `${process.env.DOMAIN}/api/file/${exists.id}`,
|
||||
repeated: true,
|
||||
repeated: true
|
||||
});
|
||||
|
||||
return Util.deleteFile(filename);
|
||||
|
@ -183,7 +183,7 @@ class uploadPOST extends Route {
|
|||
hash: file.hash,
|
||||
ip: req.ip,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
});
|
||||
} else {
|
||||
insertedId = await db.table('files').insert({
|
||||
|
@ -195,7 +195,7 @@ class uploadPOST extends Route {
|
|||
hash: file.hash,
|
||||
ip: req.ip,
|
||||
createdAt: now,
|
||||
editedAt: now,
|
||||
editedAt: now
|
||||
}, 'id');
|
||||
}
|
||||
return insertedId;
|
||||
|
|
|
@ -17,7 +17,7 @@ class apiKeyPOST extends Route {
|
|||
.where({ id: user.id })
|
||||
.update({
|
||||
apiKey,
|
||||
apiKeyEditedAt: now,
|
||||
apiKeyEditedAt: now
|
||||
});
|
||||
} catch (error) {
|
||||
dump(error);
|
||||
|
@ -26,7 +26,7 @@ class apiKeyPOST extends Route {
|
|||
|
||||
return res.json({
|
||||
message: 'Successfully created new api key',
|
||||
apiKey,
|
||||
apiKey
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class changePasswordPOST extends Route {
|
|||
const now = moment.utc().toDate();
|
||||
await db.table('users').where('id', user.id).update({
|
||||
password: hash,
|
||||
passwordEditedAt: now,
|
||||
passwordEditedAt: now
|
||||
});
|
||||
|
||||
return res.json({ message: 'The password was changed successfully' });
|
||||
|
|
|
@ -12,8 +12,8 @@ class usersGET extends Route {
|
|||
id: user.id,
|
||||
username: user.username,
|
||||
isAdmin: user.isAdmin,
|
||||
apiKey: user.apiKey,
|
||||
},
|
||||
apiKey: user.apiKey
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ class verifyGET extends Route {
|
|||
user: {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
isAdmin: user.isAdmin,
|
||||
},
|
||||
isAdmin: user.isAdmin
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ const db = require('knex')({
|
|||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_DATABASE,
|
||||
filename: nodePath.join(__dirname, '../../../database.sqlite'),
|
||||
filename: nodePath.join(__dirname, '../../../database.sqlite')
|
||||
},
|
||||
postProcessResponse: (result) => {
|
||||
/*
|
||||
|
@ -32,7 +32,7 @@ const db = require('knex')({
|
|||
if (typeof result === 'object') return processResponse(result);
|
||||
return result;
|
||||
},
|
||||
useNullAsDefault: process.env.DB_CLIENT === 'sqlite3',
|
||||
useNullAsDefault: process.env.DB_CLIENT === 'sqlite3'
|
||||
});
|
||||
const moment = require('moment');
|
||||
const log = require('../utils/Log');
|
||||
|
|
|
@ -15,7 +15,7 @@ const ThumbUtil = require('../utils/ThumbUtil');
|
|||
const rateLimiter = new RateLimit({
|
||||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW, 10),
|
||||
max: parseInt(process.env.RATE_LIMIT_MAX, 10),
|
||||
delayMs: 0,
|
||||
delayMs: 0
|
||||
});
|
||||
|
||||
class Server {
|
||||
|
@ -52,8 +52,8 @@ class Server {
|
|||
return false;
|
||||
},
|
||||
'stream': {
|
||||
write(str) { log.debug(str); },
|
||||
},
|
||||
write(str) { log.debug(str); }
|
||||
}
|
||||
}));
|
||||
}
|
||||
// this.server.use(rateLimiter);
|
||||
|
|
|
@ -4,7 +4,7 @@ class QueryHelper {
|
|||
static parsers = {
|
||||
before: (val) => QueryHelper.parseChronoList(val),
|
||||
after: (val) => QueryHelper.parseChronoList(val),
|
||||
tag: (val) => QueryHelper.sanitizeTags(val),
|
||||
tag: (val) => QueryHelper.sanitizeTags(val)
|
||||
};
|
||||
|
||||
static requirementHandlers = {
|
||||
|
@ -13,14 +13,14 @@ class QueryHelper {
|
|||
.join('albums', 'albumsFiles.albumId', '=', 'album.id'),
|
||||
tag: (knex) => knex
|
||||
.join('fileTags', 'files.id', '=', 'fileTags.fileId')
|
||||
.join('tags', 'fileTags.tagId', '=', 'tags.id'),
|
||||
.join('tags', 'fileTags.tagId', '=', 'tags.id')
|
||||
}
|
||||
|
||||
static fieldToSQLMapping = {
|
||||
album: 'albums.name',
|
||||
tag: 'tags.name',
|
||||
before: 'files.createdAt',
|
||||
after: 'files.createdAt',
|
||||
after: 'files.createdAt'
|
||||
}
|
||||
|
||||
static handlers = {
|
||||
|
@ -53,7 +53,7 @@ class QueryHelper {
|
|||
}
|
||||
}
|
||||
return knex;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
static verify(field, list) {
|
||||
|
|
|
@ -51,7 +51,7 @@ class ThumbUtil {
|
|||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: ThumbUtil.squareThumbPath,
|
||||
size: '64x64',
|
||||
size: '64x64'
|
||||
})
|
||||
.on('error', (error) => log.error(error.message));
|
||||
|
||||
|
@ -60,7 +60,7 @@ class ThumbUtil {
|
|||
timestamps: [0],
|
||||
filename: '%b.png',
|
||||
folder: ThumbUtil.thumbPath,
|
||||
size: '150x?',
|
||||
size: '150x?'
|
||||
})
|
||||
.on('error', (error) => log.error(error.message));
|
||||
|
||||
|
@ -69,7 +69,7 @@ class ThumbUtil {
|
|||
input: filePath,
|
||||
width: 150,
|
||||
output: path.join(ThumbUtil.videoPreviewPath, output),
|
||||
log: log.debug,
|
||||
log: log.debug
|
||||
});
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
|
@ -87,7 +87,7 @@ class ThumbUtil {
|
|||
if (isVideo) {
|
||||
return {
|
||||
thumb: `${filename.slice(0, -ext.length)}.png`,
|
||||
preview: `${filename.slice(0, -ext.length)}.webm`,
|
||||
preview: `${filename.slice(0, -ext.length)}.webm`
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ const db = require('knex')({
|
|||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_DATABASE,
|
||||
filename: path.join(__dirname, '../../../database.sqlite'),
|
||||
filename: path.join(__dirname, '../../../database.sqlite')
|
||||
},
|
||||
useNullAsDefault: process.env.DB_CLIENT === 'sqlite',
|
||||
useNullAsDefault: process.env.DB_CLIENT === 'sqlite'
|
||||
});
|
||||
const moment = require('moment');
|
||||
const crypto = require('crypto');
|
||||
|
@ -25,7 +25,7 @@ const ThumbUtil = require('./ThumbUtil');
|
|||
const blockedExtensions = process.env.BLOCKED_EXTENSIONS.split(',');
|
||||
|
||||
class Util {
|
||||
static uploadPath = path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER);
|
||||
static uploadPath = path.join(__dirname, '../../../', process.env.UPLOAD_FOLDER);
|
||||
|
||||
static uuid() {
|
||||
return uuidv4();
|
||||
|
@ -54,7 +54,7 @@ class Util {
|
|||
const retry = (i = 0) => {
|
||||
const filename = randomstring.generate({
|
||||
length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
|
||||
capitalization: 'lowercase',
|
||||
capitalization: 'lowercase'
|
||||
}) + path.extname(name).toLowerCase();
|
||||
|
||||
// TODO: Change this to look for the file in the db instead of in the filesystem
|
||||
|
@ -71,7 +71,7 @@ class Util {
|
|||
const retry = async (i = 0) => {
|
||||
const identifier = randomstring.generate({
|
||||
length: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10),
|
||||
capitalization: 'lowercase',
|
||||
capitalization: 'lowercase'
|
||||
});
|
||||
const exists = await db
|
||||
.table('links')
|
||||
|
@ -214,13 +214,11 @@ class Util {
|
|||
zip.writeZip(
|
||||
path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'..',
|
||||
'../../../',
|
||||
process.env.UPLOAD_FOLDER,
|
||||
'zips',
|
||||
`${album.userId}-${album.id}.zip`,
|
||||
),
|
||||
`${album.userId}-${album.id}.zip`
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
|
|
|
@ -38,7 +38,7 @@ module.exports = async (opts) => {
|
|||
|
||||
fragmentDurationSecond = 3,
|
||||
ignoreBeforePercent = 0.25,
|
||||
ignoreAfterPercent = 0.75,
|
||||
ignoreAfterPercent = 0.75
|
||||
} = opts;
|
||||
|
||||
const info = await probe(input);
|
||||
|
|
|
@ -16,7 +16,7 @@ module.exports = async (opts) => {
|
|||
output,
|
||||
|
||||
numFrames,
|
||||
numFramesPercent = 0.05,
|
||||
numFramesPercent = 0.05
|
||||
} = opts;
|
||||
|
||||
const info = await probe(input);
|
||||
|
@ -32,7 +32,7 @@ module.exports = async (opts) => {
|
|||
|
||||
const result = {
|
||||
output,
|
||||
numFrames: numFramesToCapture,
|
||||
numFrames: numFramesToCapture
|
||||
};
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
|
|
36
src/setup.js
36
src/setup.js
|
@ -5,7 +5,7 @@ const qoa = require('qoa');
|
|||
|
||||
qoa.config({
|
||||
prefix: '>',
|
||||
underlineQuery: false,
|
||||
underlineQuery: false
|
||||
});
|
||||
|
||||
async function start() {
|
||||
|
@ -17,53 +17,53 @@ async function start() {
|
|||
{
|
||||
type: 'input',
|
||||
query: 'Port to run lolisafe in:',
|
||||
handle: 'SERVER_PORT',
|
||||
handle: 'SERVER_PORT'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Full domain this instance is gonna be running on (Ex: https://lolisafe.moe):',
|
||||
handle: 'DOMAIN',
|
||||
handle: 'DOMAIN'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Name of the service? (Ex: lolisafe):',
|
||||
handle: 'SERVICE_NAME',
|
||||
handle: 'SERVICE_NAME'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Maximum allowed upload file size in MB (Ex: 100):',
|
||||
handle: 'MAX_SIZE',
|
||||
handle: 'MAX_SIZE'
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
query: 'Allow users to download entire albums in ZIP format?',
|
||||
handle: 'GENERATE_ZIPS',
|
||||
accept: 'y',
|
||||
deny: 'n',
|
||||
deny: 'n'
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
query: 'Allow people to upload files without an account?',
|
||||
handle: 'PUBLIC_MODE',
|
||||
accept: 'y',
|
||||
deny: 'n',
|
||||
deny: 'n'
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
query: 'Allow people to create new accounts?',
|
||||
handle: 'USER_ACCOUNTS',
|
||||
accept: 'y',
|
||||
deny: 'n',
|
||||
deny: 'n'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Name of the admin account?',
|
||||
handle: 'ADMIN_ACCOUNT',
|
||||
handle: 'ADMIN_ACCOUNT'
|
||||
},
|
||||
{
|
||||
type: 'secure',
|
||||
query: 'Type a secure password for the admin account:',
|
||||
handle: 'ADMIN_PASSWORD',
|
||||
handle: 'ADMIN_PASSWORD'
|
||||
},
|
||||
{
|
||||
type: 'interactive',
|
||||
|
@ -73,29 +73,29 @@ async function start() {
|
|||
menu: [
|
||||
'sqlite3',
|
||||
'pg',
|
||||
'mysql',
|
||||
],
|
||||
'mysql'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Database host (Ignore if you selected sqlite3):',
|
||||
handle: 'DB_HOST',
|
||||
handle: 'DB_HOST'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Database user (Ignore if you selected sqlite3):',
|
||||
handle: 'DB_USER',
|
||||
handle: 'DB_USER'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Database password (Ignore if you selected sqlite3):',
|
||||
handle: 'DB_PASSWORD',
|
||||
handle: 'DB_PASSWORD'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
query: 'Database name (Ignore if you selected sqlite3):',
|
||||
handle: 'DB_DATABASE',
|
||||
},
|
||||
handle: 'DB_DATABASE'
|
||||
}
|
||||
];
|
||||
|
||||
const response = await qoa.prompt(wizard);
|
||||
|
@ -118,7 +118,7 @@ async function start() {
|
|||
META_THEME_COLOR: '#20222b',
|
||||
META_DESCRIPTION: 'Blazing fast file uploader and bunker written in node! 🚀',
|
||||
META_KEYWORDS: 'lolisafe,upload,uploader,file,vue,images,ssr,file uploader,free',
|
||||
META_TWITTER_HANDLE: '@its_pitu',
|
||||
META_TWITTER_HANDLE: '@its_pitu'
|
||||
};
|
||||
|
||||
const allSettings = Object.assign(defaultSettings, response);
|
||||
|
|
|
@ -120,17 +120,17 @@ export default {
|
|||
props: {
|
||||
albumId: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
details: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isCreatingLink: false,
|
||||
isDeletingLinks: [],
|
||||
isDeletingLinks: []
|
||||
};
|
||||
},
|
||||
computed: mapState(['config', 'auth']),
|
||||
|
@ -141,20 +141,20 @@ export default {
|
|||
updateLinkOptionsAction: 'albums/updateLinkOptions',
|
||||
createLinkAction: 'albums/createLink',
|
||||
createCustomLinkAction: 'albums/createCustomLink',
|
||||
alert: 'alert/set',
|
||||
alert: 'alert/set'
|
||||
}),
|
||||
promptDeleteAlbum(id) {
|
||||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to delete this album?',
|
||||
onConfirm: () => this.deleteAlbum(id),
|
||||
onConfirm: () => this.deleteAlbum(id)
|
||||
});
|
||||
},
|
||||
promptDeleteAlbumLink(albumId, identifier) {
|
||||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to delete this album link?',
|
||||
onConfirm: () => this.deleteAlbumLink(albumId, identifier),
|
||||
onConfirm: () => this.deleteAlbumLink(albumId, identifier)
|
||||
});
|
||||
},
|
||||
async deleteAlbum(id) {
|
||||
|
@ -204,16 +204,16 @@ export default {
|
|||
message: 'Custom link identifier',
|
||||
inputAttrs: {
|
||||
placeholder: '',
|
||||
maxlength: 10,
|
||||
maxlength: 10
|
||||
},
|
||||
trapFocus: true,
|
||||
onConfirm: (value) => this.$handler.executeAction('albums/createCustomLink', { albumId, value }),
|
||||
onConfirm: (value) => this.$handler.executeAction('albums/createCustomLink', { albumId, value })
|
||||
});
|
||||
},
|
||||
isDeleting(identifier) {
|
||||
return this.isDeletingLinks.indexOf(identifier) > -1;
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -63,22 +63,22 @@ import AlbumDetails from '~/components/album/AlbumDetails.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
AlbumDetails,
|
||||
AlbumDetails
|
||||
},
|
||||
props: {
|
||||
album: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isExpandedGetter: 'albums/isExpanded',
|
||||
getDetails: 'albums/getDetails',
|
||||
getDetails: 'albums/getDetails'
|
||||
}),
|
||||
isExpanded() {
|
||||
return this.isExpandedGetter(this.album.id);
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async toggleDetails(album) {
|
||||
|
@ -86,8 +86,8 @@ export default {
|
|||
await this.$store.dispatch('albums/fetchDetails', album.id);
|
||||
}
|
||||
this.$store.commit('albums/toggleExpandedState', album.id);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -81,8 +81,8 @@ export default {
|
|||
...mapState({
|
||||
version: (state) => state.config.version,
|
||||
serviceName: (state) => state.config.serviceName,
|
||||
token: (state) => state.auth.token,
|
||||
}),
|
||||
token: (state) => state.auth.token
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
createShareXThing() {
|
||||
|
@ -102,8 +102,8 @@ export default {
|
|||
}`;
|
||||
const sharexBlob = new Blob([sharexFile], { type: 'application/octet-binary' });
|
||||
saveAs(sharexBlob, `${location.hostname}.sxcu`);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -162,37 +162,37 @@ import ImageInfo from '~/components/image-modal/ImageInfo.vue';
|
|||
export default {
|
||||
components: {
|
||||
Waterfall,
|
||||
ImageInfo,
|
||||
ImageInfo
|
||||
},
|
||||
props: {
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
isPublic: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 150,
|
||||
default: 150
|
||||
},
|
||||
enableSearch: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
enableToolbar: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -208,15 +208,15 @@ export default {
|
|||
modalData: {
|
||||
file: null,
|
||||
tags: null,
|
||||
albums: null,
|
||||
},
|
||||
albums: null
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
user: (state) => state.auth.user,
|
||||
albums: (state) => state.albums.tinyDetails,
|
||||
images: (state) => state.images,
|
||||
images: (state) => state.images
|
||||
}),
|
||||
blank() {
|
||||
// eslint-disable-next-line global-require, import/no-unresolved
|
||||
|
@ -224,7 +224,7 @@ export default {
|
|||
},
|
||||
gridFiles() {
|
||||
return (this.files || []).filter((v) => !v.hideFromList);
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// TODO: Create a middleware for this
|
||||
|
@ -251,7 +251,7 @@ export default {
|
|||
} catch (e) {
|
||||
this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true });
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
isAlbumSelected(id) {
|
||||
|
@ -279,12 +279,12 @@ export default {
|
|||
if (add) {
|
||||
response = await this.$store.dispatch('images/addToAlbum', {
|
||||
albumId: id,
|
||||
fileId: this.showingModalForFile.id,
|
||||
fileId: this.showingModalForFile.id
|
||||
});
|
||||
} else {
|
||||
response = await this.$store.dispatch('images/removeFromAlbum', {
|
||||
albumId: id,
|
||||
fileId: this.showingModalForFile.id,
|
||||
fileId: this.showingModalForFile.id
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -332,8 +332,8 @@ export default {
|
|||
},
|
||||
isHovered(id) {
|
||||
return this.hoveredItems.includes(id);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -20,29 +20,29 @@ const imagesloaded = isBrowser ? require('imagesloaded') : null;
|
|||
export default {
|
||||
name: 'Waterfall',
|
||||
components: {
|
||||
WaterfallItem,
|
||||
WaterfallItem
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
default: () => {}
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
itemWidth: {
|
||||
type: Number,
|
||||
default: 150,
|
||||
default: 150
|
||||
},
|
||||
gutterWidth: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
default: 10
|
||||
},
|
||||
gutterHeight: {
|
||||
type: Number,
|
||||
default: 4,
|
||||
},
|
||||
default: 4
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initializeMasonry();
|
||||
|
@ -62,7 +62,7 @@ export default {
|
|||
node,
|
||||
() => {
|
||||
this.masonry.layout();
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
performLayout() {
|
||||
|
@ -101,7 +101,7 @@ export default {
|
|||
removed,
|
||||
appended,
|
||||
prepended,
|
||||
moved,
|
||||
moved
|
||||
};
|
||||
},
|
||||
initializeMasonry() {
|
||||
|
@ -111,8 +111,8 @@ export default {
|
|||
{
|
||||
columnWidth: this.itemWidth,
|
||||
gutter: this.gutterWidth,
|
||||
...this.options,
|
||||
},
|
||||
...this.options
|
||||
}
|
||||
);
|
||||
this.domChildren = this.getNewDomChildren();
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ export default {
|
|||
const children = this.options && this.options.itemSelector
|
||||
? node.querySelectorAll(this.options.itemSelector) : node.children;
|
||||
return Array.prototype.slice.call(children);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'WaterfallItem',
|
||||
name: 'WaterfallItem'
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="links">
|
||||
<a href="https://github.com/WeebDev/lolisafe"
|
||||
<a
|
||||
href="https://github.com/WeebDev/lolisafe"
|
||||
target="_blank"
|
||||
class="link">
|
||||
<header class="bd-footer-star-header">
|
||||
|
@ -8,15 +9,21 @@
|
|||
<p class="bd-footer-subtitle">Deploy your own lolisafe</p>
|
||||
</header>
|
||||
</a>
|
||||
<div v-if="loggedIn"
|
||||
<div
|
||||
v-if="loggedIn"
|
||||
class="link"
|
||||
@click="createShareXThing">
|
||||
<header class="bd-footer-star-header">
|
||||
<h4 class="bd-footer-title">ShareX</h4>
|
||||
<p class="bd-footer-subtitle">Upload from your Desktop</p>
|
||||
<h4 class="bd-footer-title">
|
||||
ShareX
|
||||
</h4>
|
||||
<p class="bd-footer-subtitle">
|
||||
Upload from your Desktop
|
||||
</p>
|
||||
</header>
|
||||
</div>
|
||||
<a href="https://chrome.google.com/webstore/detail/lolisafe-uploader/enkkmplljfjppcdaancckgilmgoiofnj"
|
||||
<a
|
||||
href="https://chrome.google.com/webstore/detail/lolisafe-uploader/enkkmplljfjppcdaancckgilmgoiofnj"
|
||||
target="_blank"
|
||||
class="link">
|
||||
<header class="bd-footer-star-header">
|
||||
|
@ -24,17 +31,23 @@
|
|||
<p class="bd-footer-subtitle">Upload from any website</p>
|
||||
</header>
|
||||
</a>
|
||||
<router-link to="/faq"
|
||||
<router-link
|
||||
to="/faq"
|
||||
class="link">
|
||||
<header class="bd-footer-star-header">
|
||||
<h4 class="bd-footer-title">FAQ</h4>
|
||||
<p class="bd-footer-subtitle">We got you covered</p>
|
||||
<h4 class="bd-footer-title">
|
||||
FAQ
|
||||
</h4>
|
||||
<p class="bd-footer-subtitle">
|
||||
We got you covered
|
||||
</p>
|
||||
</header>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
loggedIn() {
|
||||
|
|
|
@ -31,21 +31,21 @@ export default {
|
|||
props: {
|
||||
imageId: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
imageAlbums: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
albums: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedOptions: [],
|
||||
orderedAlbums: [],
|
||||
orderedAlbums: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
return selectedA ? -1 : 1;
|
||||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
isAlbumSelected(id) {
|
||||
|
@ -78,15 +78,15 @@ export default {
|
|||
if (this.selectedOptions.indexOf(id) > -1) {
|
||||
this.$handler.executeAction('images/addToAlbum', {
|
||||
albumId: id,
|
||||
fileId: this.imageId,
|
||||
fileId: this.imageId
|
||||
});
|
||||
} else {
|
||||
this.$handler.executeAction('images/removeFromAlbum', {
|
||||
albumId: id,
|
||||
fileId: this.imageId,
|
||||
fileId: this.imageId
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -118,25 +118,25 @@ import Taginfo from './TagInfo.vue';
|
|||
export default {
|
||||
components: {
|
||||
Taginfo,
|
||||
Albuminfo,
|
||||
Albuminfo
|
||||
},
|
||||
props: {
|
||||
file: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
default: () => ({})
|
||||
},
|
||||
albums: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
default: () => ([])
|
||||
},
|
||||
tags: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
},
|
||||
default: () => ([])
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
images: (state) => state.images,
|
||||
tinyDetails: (state) => state.albums.tinyDetails,
|
||||
tinyDetails: (state) => state.albums.tinyDetails
|
||||
}),
|
||||
methods: {
|
||||
formatBytes(bytes, decimals = 2) {
|
||||
|
@ -152,8 +152,8 @@ export default {
|
|||
},
|
||||
isVideo(type) {
|
||||
return type.startsWith('video');
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -23,24 +23,24 @@ export default {
|
|||
props: {
|
||||
imageId: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
imageTags: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filteredTags: [],
|
||||
filteredTags: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
tags: (state) => state.tags.tagsList,
|
||||
tags: (state) => state.tags.tagsList
|
||||
}),
|
||||
selectedTags() { return this.imageTags.map((e) => e.name); },
|
||||
lowercaseTags() { return this.imageTags.map((e) => e.name.toLowerCase()); },
|
||||
lowercaseTags() { return this.imageTags.map((e) => e.name.toLowerCase()); }
|
||||
},
|
||||
methods: {
|
||||
getFilteredTags(str) {
|
||||
|
@ -78,8 +78,8 @@ export default {
|
|||
},
|
||||
tagRemoved(tag) {
|
||||
this.$handler.executeAction('images/removeTag', { fileId: this.imageId, tagName: tag });
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,16 +9,16 @@ export default {
|
|||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: '60px',
|
||||
default: '60px'
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
default: '#9C27B0',
|
||||
default: '#9C27B0'
|
||||
},
|
||||
duration: {
|
||||
type: String,
|
||||
default: '1.8s',
|
||||
},
|
||||
default: '1.8s'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styles() {
|
||||
|
@ -26,10 +26,10 @@ export default {
|
|||
width: this.size,
|
||||
height: this.size,
|
||||
backgroundColor: this.background,
|
||||
animationDuration: this.duration,
|
||||
animationDuration: this.duration
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ export default {
|
|||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: '40px',
|
||||
},
|
||||
default: '40px'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
innerStyles() {
|
||||
|
@ -31,10 +31,10 @@ export default {
|
|||
styles() {
|
||||
return {
|
||||
width: this.size,
|
||||
height: this.size,
|
||||
height: this.size
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ export default {
|
|||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: '60px',
|
||||
},
|
||||
default: '60px'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
innerStyles() {
|
||||
|
@ -30,10 +30,10 @@ export default {
|
|||
styles() {
|
||||
return {
|
||||
width: this.size,
|
||||
height: this.size,
|
||||
height: this.size
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,18 +9,18 @@ export default {
|
|||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: '40px',
|
||||
},
|
||||
default: '40px'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styles() {
|
||||
return {
|
||||
width: this.size,
|
||||
height: this.size,
|
||||
display: 'inline-block',
|
||||
display: 'inline-block'
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -73,22 +73,22 @@ export default {
|
|||
props: {
|
||||
isWhite: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return { hamburger: false };
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ loggedIn: 'auth/isLoggedIn' }),
|
||||
...mapState(['config']),
|
||||
...mapState(['config'])
|
||||
},
|
||||
methods: {
|
||||
async logOut() {
|
||||
await this.$store.dispatch('auth/logout');
|
||||
this.$router.replace('/login');
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -90,11 +90,11 @@ export default {
|
|||
value: [Number, String],
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
field: {
|
||||
type: String,
|
||||
default: 'value',
|
||||
default: 'value'
|
||||
},
|
||||
keepFirst: Boolean,
|
||||
clearOnSelect: Boolean,
|
||||
|
@ -106,12 +106,12 @@ export default {
|
|||
maxHeight: [String, Number],
|
||||
dropdownPosition: {
|
||||
type: String,
|
||||
default: 'auto',
|
||||
default: 'auto'
|
||||
},
|
||||
iconRight: String,
|
||||
iconRightClickable: Boolean,
|
||||
appendToBody: Boolean,
|
||||
customSelector: Function,
|
||||
customSelector: Function
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -125,7 +125,7 @@ export default {
|
|||
style: {},
|
||||
_isAutocomplete: true,
|
||||
_elementRef: 'input',
|
||||
_bodyEl: undefined, // Used to append to body
|
||||
_bodyEl: undefined // Used to append to body
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -202,9 +202,9 @@ export default {
|
|||
// eslint-disable-next-line no-nested-ternary
|
||||
maxHeight: this.maxHeight === undefined
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
? null : (isNaN(this.maxHeight) ? this.maxHeight : `${this.maxHeight}px`),
|
||||
? null : (isNaN(this.maxHeight) ? this.maxHeight : `${this.maxHeight}px`)
|
||||
};
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
/**
|
||||
|
@ -258,7 +258,7 @@ export default {
|
|||
if (this.keepFirst) {
|
||||
this.selectFirstOption(value);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (typeof window !== 'undefined') {
|
||||
|
@ -507,10 +507,10 @@ export default {
|
|||
left: `${left}px`,
|
||||
width: `${trigger.clientWidth}px`,
|
||||
maxWidth: `${trigger.clientWidth}px`,
|
||||
zIndex: '99',
|
||||
zIndex: '99'
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -36,13 +36,13 @@ import SearchInput from '~/components/search-input/SearchInput.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
SearchInput,
|
||||
SearchInput
|
||||
},
|
||||
props: {
|
||||
hiddenHints: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -51,35 +51,35 @@ export default {
|
|||
{
|
||||
'name': 'tag',
|
||||
'valueFormat': 'name',
|
||||
'hint': '',
|
||||
'hint': ''
|
||||
},
|
||||
{
|
||||
'name': 'album',
|
||||
'valueFormat': 'name',
|
||||
'hint': '',
|
||||
'hint': ''
|
||||
},
|
||||
{
|
||||
'name': 'before',
|
||||
'valueFormat': 'specific date',
|
||||
'hint': '',
|
||||
'hint': ''
|
||||
},
|
||||
{
|
||||
'name': 'during',
|
||||
'valueFormat': 'specific date',
|
||||
'hint': '',
|
||||
'hint': ''
|
||||
},
|
||||
{
|
||||
'name': 'after',
|
||||
'valueFormat': 'specific date',
|
||||
'hint': '',
|
||||
'hint': ''
|
||||
},
|
||||
{
|
||||
'name': 'file',
|
||||
'valueFormat': 'generated name',
|
||||
'hint': '',
|
||||
},
|
||||
'hint': ''
|
||||
}
|
||||
],
|
||||
filteredHints: [],
|
||||
filteredHints: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -122,8 +122,8 @@ export default {
|
|||
if (/:$/gi.test(this.query)) { return; }
|
||||
}
|
||||
this.$emit('search', this.query, event);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ import { mapState } from 'vuex';
|
|||
|
||||
export default {
|
||||
computed: mapState({
|
||||
user: (state) => state.auth.user,
|
||||
user: (state) => state.auth.user
|
||||
}),
|
||||
methods: {
|
||||
isRouteActive(id) {
|
||||
|
@ -56,8 +56,8 @@ export default {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
|
|
@ -88,15 +88,15 @@ export default {
|
|||
files: [],
|
||||
dropzoneOptions: {},
|
||||
showDropzone: false,
|
||||
selectedAlbum: null,
|
||||
selectedAlbum: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
config: (state) => state.config,
|
||||
albums: (state) => state.albums.tinyDetails,
|
||||
albums: (state) => state.albums.tinyDetails
|
||||
}),
|
||||
...mapGetters({ loggedIn: 'auth/isLoggedIn', token: 'auth/getToken' }),
|
||||
...mapGetters({ loggedIn: 'auth/isLoggedIn', token: 'auth/getToken' })
|
||||
},
|
||||
watch: {
|
||||
loggedIn() {
|
||||
|
@ -104,7 +104,7 @@ export default {
|
|||
},
|
||||
selectedAlbum() {
|
||||
this.updateDropzoneConfig();
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.dropzoneOptions = {
|
||||
|
@ -127,7 +127,7 @@ export default {
|
|||
maxFilesize: this.config.maxFileSize,
|
||||
previewTemplate: this.$refs.template.innerHTML,
|
||||
dictDefaultMessage: 'Drag & Drop your files or click to browse',
|
||||
headers: { Accept: 'application/vnd.lolisafe.json' },
|
||||
headers: { Accept: 'application/vnd.lolisafe.json' }
|
||||
};
|
||||
this.showDropzone = true;
|
||||
if (this.loggedIn) this.getAlbums();
|
||||
|
@ -154,7 +154,7 @@ export default {
|
|||
this.$refs.el.setOption('headers', {
|
||||
Accept: 'application/vnd.lolisafe.json',
|
||||
Authorization: this.token ? `Bearer ${this.token}` : '',
|
||||
albumId: this.selectedAlbum ? this.selectedAlbum : null,
|
||||
albumId: this.selectedAlbum ? this.selectedAlbum : null
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -170,7 +170,7 @@ export default {
|
|||
dropzoneError(file, message, xhr) {
|
||||
this.$store.dispatch('alert', {
|
||||
text: 'There was an error uploading this file. Check the console.',
|
||||
error: true,
|
||||
error: true
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(file, message, xhr);
|
||||
|
@ -182,8 +182,8 @@ export default {
|
|||
original: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
count: file.upload.totalChunkCount,
|
||||
}],
|
||||
count: file.upload.totalChunkCount
|
||||
}]
|
||||
});
|
||||
|
||||
this.processResult(file, data);
|
||||
|
@ -205,8 +205,8 @@ export default {
|
|||
this.$clipboard(response.url);
|
||||
});
|
||||
*/
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -6,5 +6,5 @@ export default {
|
|||
ERROR: 'is-danger',
|
||||
DARK: 'is-dark',
|
||||
LIGHT: 'is-light',
|
||||
WHITE: 'is-white',
|
||||
WHITE: 'is-white'
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ import Footer from '~/components/footer/Footer.vue';
|
|||
export default {
|
||||
components: {
|
||||
Navbar,
|
||||
Footer,
|
||||
Footer
|
||||
},
|
||||
computed: mapState(['config', 'alert']),
|
||||
created() {
|
||||
|
@ -33,14 +33,14 @@ export default {
|
|||
duration: 3500,
|
||||
position: 'is-bottom',
|
||||
message,
|
||||
type,
|
||||
type
|
||||
});
|
||||
} else {
|
||||
this.$buefy.toast.open({
|
||||
duration: 3500,
|
||||
position: 'is-bottom',
|
||||
message,
|
||||
type,
|
||||
type
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,9 @@ export default {
|
|||
`%c lolisafe %c v${this.config.version} %c`,
|
||||
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
|
||||
'background:#ff015b; padding: 1px; border-radius: 0 3px 3px 0; color: #fff',
|
||||
'background:transparent',
|
||||
'background:transparent'
|
||||
);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
import Navbar from '~/components/navbar/Navbar.vue';
|
||||
|
||||
export default {
|
||||
components: { Navbar },
|
||||
components: { Navbar }
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -67,7 +67,7 @@ export default {
|
|||
computed: {
|
||||
config() {
|
||||
return this.$store.state.config;
|
||||
},
|
||||
}
|
||||
},
|
||||
async asyncData({ app, params, error }) {
|
||||
try {
|
||||
|
@ -77,7 +77,7 @@ export default {
|
|||
name: data.name,
|
||||
downloadEnabled: data.downloadEnabled,
|
||||
files: data.files,
|
||||
downloadLink,
|
||||
downloadLink
|
||||
};
|
||||
} catch (err) {
|
||||
console.log('Error when retrieving album', err);
|
||||
|
@ -100,8 +100,8 @@ export default {
|
|||
{ vmid: 'og:title', property: 'og:title', content: `Album: ${this.name} | Files: ${this.files.length}` },
|
||||
{ vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' },
|
||||
{ vmid: 'og:image', property: 'og:image', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` },
|
||||
{ vmid: 'og:image:secure_url', property: 'og:image:secure_url', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` },
|
||||
],
|
||||
{ vmid: 'og:image:secure_url', property: 'og:image:secure_url', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }
|
||||
]
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
@ -113,9 +113,9 @@ export default {
|
|||
{ vmid: 'twitter:description', name: 'twitter:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' },
|
||||
{ vmid: 'og:url', property: 'og:url', content: `${this.config.URL}/a/${this.$route.params.identifier}` },
|
||||
{ vmid: 'og:title', property: 'og:title', content: 'lolisafe' },
|
||||
{ vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' },
|
||||
],
|
||||
{ vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }
|
||||
]
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -102,7 +102,7 @@ import Sidebar from '~/components/sidebar/Sidebar.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Sidebar
|
||||
},
|
||||
middleware: ['auth', ({ store }) => {
|
||||
store.dispatch('auth/fetchCurrentUser');
|
||||
|
@ -111,21 +111,21 @@ export default {
|
|||
return {
|
||||
password: '',
|
||||
newPassword: '',
|
||||
reNewPassword: '',
|
||||
reNewPassword: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ 'apiKey': 'auth/getApiKey' }),
|
||||
...mapState({
|
||||
user: (state) => state.auth.user,
|
||||
}),
|
||||
user: (state) => state.auth.user
|
||||
})
|
||||
},
|
||||
metaInfo() {
|
||||
return { title: 'Account' };
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
getUserSetttings: 'auth/fetchCurrentUser',
|
||||
getUserSetttings: 'auth/fetchCurrentUser'
|
||||
}),
|
||||
async changePassword() {
|
||||
const { password, newPassword, reNewPassword } = this;
|
||||
|
@ -133,21 +133,21 @@ export default {
|
|||
if (!password || !newPassword || !reNewPassword) {
|
||||
this.$store.dispatch('alert/set', {
|
||||
text: 'One or more fields are missing',
|
||||
error: true,
|
||||
error: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (newPassword !== reNewPassword) {
|
||||
this.$store.dispatch('alert/set', {
|
||||
text: 'Passwords don\'t match',
|
||||
error: true,
|
||||
error: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await this.$store.dispatch('auth/changePassword', {
|
||||
password,
|
||||
newPassword,
|
||||
newPassword
|
||||
});
|
||||
|
||||
if (response) {
|
||||
|
@ -158,7 +158,7 @@ export default {
|
|||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to regenerate your API key? Previously generated API keys will stop working. Make sure to write the new key down as this is the only time it will be displayed to you.',
|
||||
onConfirm: () => this.requestNewAPIKey(),
|
||||
onConfirm: () => this.requestNewAPIKey()
|
||||
});
|
||||
},
|
||||
copyKey() {
|
||||
|
@ -168,7 +168,7 @@ export default {
|
|||
async requestNewAPIKey() {
|
||||
const response = await this.$store.dispatch('auth/requestAPIKey');
|
||||
this.$buefy.toast.open(response.message);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -127,7 +127,7 @@ import Sidebar from '~/components/sidebar/Sidebar.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Sidebar
|
||||
},
|
||||
middleware: ['auth', 'admin', ({ route, store }) => {
|
||||
try {
|
||||
|
@ -143,7 +143,7 @@ export default {
|
|||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to disable the account of the user that uploaded this file?',
|
||||
onConfirm: () => this.disableUser(),
|
||||
onConfirm: () => this.disableUser()
|
||||
});
|
||||
},
|
||||
disableUser() {
|
||||
|
@ -153,7 +153,7 @@ export default {
|
|||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to ban the IP this file was uploaded from?',
|
||||
onConfirm: () => this.banIP(),
|
||||
onConfirm: () => this.banIP()
|
||||
});
|
||||
},
|
||||
banIP() {
|
||||
|
@ -169,7 +169,7 @@ export default {
|
|||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -131,7 +131,7 @@ import Sidebar from '~/components/sidebar/Sidebar.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Sidebar
|
||||
},
|
||||
middleware: ['auth', 'admin', ({ store }) => {
|
||||
try {
|
||||
|
@ -145,18 +145,18 @@ export default {
|
|||
return { title: 'Settings' };
|
||||
},
|
||||
computed: mapState({
|
||||
settings: (state) => state.admin.settings,
|
||||
settings: (state) => state.admin.settings
|
||||
}),
|
||||
methods: {
|
||||
promptRestartService() {
|
||||
this.$buefy.dialog.confirm({
|
||||
message: 'Keep in mind that restarting only works if you have PM2 or something similar set up. Continue?',
|
||||
onConfirm: () => this.restartService(),
|
||||
onConfirm: () => this.restartService()
|
||||
});
|
||||
},
|
||||
restartService() {
|
||||
this.$handler.executeAction('admin/restartService');
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -76,7 +76,7 @@ import Grid from '~/components/grid/Grid.vue';
|
|||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Grid,
|
||||
Grid
|
||||
},
|
||||
middleware: ['auth', 'admin', ({ route, store }) => {
|
||||
try {
|
||||
|
@ -88,25 +88,25 @@ export default {
|
|||
}],
|
||||
data() {
|
||||
return {
|
||||
options: {},
|
||||
options: {}
|
||||
};
|
||||
},
|
||||
computed: mapState({
|
||||
user: (state) => state.admin.user,
|
||||
user: (state) => state.admin.user
|
||||
}),
|
||||
methods: {
|
||||
promptDisableUser() {
|
||||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to disable the account of this user?',
|
||||
onConfirm: () => this.disableUser(),
|
||||
onConfirm: () => this.disableUser()
|
||||
});
|
||||
},
|
||||
promptEnableUser() {
|
||||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to enable the account of this user?',
|
||||
onConfirm: () => this.enableUser(),
|
||||
onConfirm: () => this.enableUser()
|
||||
});
|
||||
},
|
||||
disableUser() {
|
||||
|
@ -114,7 +114,7 @@ export default {
|
|||
},
|
||||
enableUser() {
|
||||
this.$handler.executeAction('admin/enableUser', this.user.id);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -91,7 +91,7 @@ import Sidebar from '~/components/sidebar/Sidebar.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Sidebar
|
||||
},
|
||||
middleware: ['auth', 'admin', ({ route, store }) => {
|
||||
try {
|
||||
|
@ -103,7 +103,7 @@ export default {
|
|||
}],
|
||||
computed: mapState({
|
||||
users: (state) => state.admin.users,
|
||||
config: (state) => state.config,
|
||||
config: (state) => state.config
|
||||
}),
|
||||
metaInfo() {
|
||||
return { title: 'Uploads' };
|
||||
|
@ -126,13 +126,13 @@ export default {
|
|||
promptPurgeFiles(row) {
|
||||
this.$buefy.dialog.confirm({
|
||||
message: 'Are you sure you want to delete this user\'s files?',
|
||||
onConfirm: () => this.purgeFiles(row),
|
||||
onConfirm: () => this.purgeFiles(row)
|
||||
});
|
||||
},
|
||||
async purgeFiles(row) {
|
||||
this.$handler.executeAction('admin/purgeUserFiles', row.id);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
|||
components: {
|
||||
Sidebar,
|
||||
Grid,
|
||||
Search,
|
||||
Search
|
||||
},
|
||||
middleware: ['auth', ({ route, store }) => {
|
||||
store.commit('images/resetState');
|
||||
|
@ -80,34 +80,34 @@ export default {
|
|||
}],
|
||||
data() {
|
||||
return {
|
||||
current: 1,
|
||||
current: 1
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
totalFiles: 'images/getTotalFiles',
|
||||
shouldPaginate: 'images/shouldPaginate',
|
||||
limit: 'images/getLimit',
|
||||
limit: 'images/getLimit'
|
||||
}),
|
||||
...mapState(['images']),
|
||||
id() {
|
||||
return this.$route.params.id;
|
||||
},
|
||||
}
|
||||
},
|
||||
metaInfo() {
|
||||
return { title: 'Album' };
|
||||
},
|
||||
watch: {
|
||||
current: 'fetchPaginate',
|
||||
current: 'fetchPaginate'
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
fetch: 'images/fetchByAlbumId',
|
||||
fetch: 'images/fetchByAlbumId'
|
||||
}),
|
||||
fetchPaginate() {
|
||||
this.fetch({ id: this.id, page: this.current });
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ import AlbumEntry from '~/components/album/AlbumEntry.vue';
|
|||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
AlbumEntry,
|
||||
AlbumEntry
|
||||
},
|
||||
middleware: ['auth', ({ store }) => {
|
||||
try {
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
newAlbumName: null,
|
||||
isCreatingAlbum: false,
|
||||
isCreatingAlbum: false
|
||||
};
|
||||
},
|
||||
computed: mapState(['config', 'albums']),
|
||||
|
@ -74,7 +74,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
'alert': 'alert/set',
|
||||
'alert': 'alert/set'
|
||||
}),
|
||||
async createAlbum() {
|
||||
if (!this.newAlbumName || this.newAlbumName === '') return;
|
||||
|
@ -90,8 +90,8 @@ export default {
|
|||
this.isCreatingAlbum = false;
|
||||
this.newAlbumName = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ export default {
|
|||
components: {
|
||||
Sidebar,
|
||||
Grid,
|
||||
Search,
|
||||
Search
|
||||
},
|
||||
middleware: ['auth', ({ store }) => {
|
||||
store.commit('images/resetState');
|
||||
|
@ -74,29 +74,29 @@ export default {
|
|||
return {
|
||||
current: 1,
|
||||
isLoading: false,
|
||||
search: '',
|
||||
search: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
totalFiles: 'images/getTotalFiles',
|
||||
shouldPaginate: 'images/shouldPaginate',
|
||||
limit: 'images/getLimit',
|
||||
limit: 'images/getLimit'
|
||||
}),
|
||||
...mapState(['images']),
|
||||
...mapState(['images'])
|
||||
},
|
||||
metaInfo() {
|
||||
return { title: 'Uploads' };
|
||||
},
|
||||
watch: {
|
||||
current: 'fetchPaginate',
|
||||
current: 'fetchPaginate'
|
||||
},
|
||||
created() {
|
||||
this.filteredHints = this.hints; // fixes the issue where on pageload, suggestions wont load
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
fetch: 'images/fetch',
|
||||
fetch: 'images/fetch'
|
||||
}),
|
||||
async fetchPaginate() {
|
||||
this.isLoading = true;
|
||||
|
@ -111,10 +111,10 @@ export default {
|
|||
onSearch(query) {
|
||||
this.search = query;
|
||||
this.$handler.executeAction('images/search', {
|
||||
q: this.sanitizeQuery(query),
|
||||
q: this.sanitizeQuery(query)
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -215,19 +215,19 @@ import Sidebar from '~/components/sidebar/Sidebar.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
Sidebar
|
||||
},
|
||||
middleware: 'auth',
|
||||
data() {
|
||||
return {
|
||||
tags: [],
|
||||
newTagName: null,
|
||||
newTagName: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
config() {
|
||||
return this.$store.state.config;
|
||||
},
|
||||
}
|
||||
},
|
||||
metaInfo() {
|
||||
return { title: 'Tags' };
|
||||
|
@ -240,7 +240,7 @@ export default {
|
|||
this.$buefy.dialog.confirm({
|
||||
type: 'is-danger',
|
||||
message: 'Are you sure you want to delete this tag?',
|
||||
onConfirm: () => this.promptPurgeTag(id),
|
||||
onConfirm: () => this.promptPurgeTag(id)
|
||||
});
|
||||
},
|
||||
promptPurgeTag(id) {
|
||||
|
@ -250,7 +250,7 @@ export default {
|
|||
cancelText: 'No',
|
||||
confirmText: 'Yes',
|
||||
onConfirm: () => this.deleteTag(id, true),
|
||||
onCancel: () => this.deleteTag(id, false),
|
||||
onCancel: () => this.deleteTag(id, false)
|
||||
});
|
||||
},
|
||||
async deleteTag(id, purge) {
|
||||
|
@ -272,7 +272,7 @@ export default {
|
|||
tag.isDetailsOpen = false;
|
||||
}
|
||||
this.tags = response.tags;
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -56,7 +56,7 @@ export default {
|
|||
},
|
||||
metaInfo() {
|
||||
return { title: 'Faq' };
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -41,15 +41,15 @@ export default {
|
|||
components: {
|
||||
Logo,
|
||||
Uploader,
|
||||
Links,
|
||||
Links
|
||||
},
|
||||
data() {
|
||||
return { albums: [] };
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ loggedIn: 'auth/isLoggedIn' }),
|
||||
...mapState(['config']),
|
||||
},
|
||||
...mapState(['config'])
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -95,7 +95,7 @@ export default {
|
|||
password: null,
|
||||
mfaCode: null,
|
||||
isMfaModalActive: false,
|
||||
isLoading: false,
|
||||
isLoading: false
|
||||
};
|
||||
},
|
||||
computed: mapState(['config', 'auth']),
|
||||
|
@ -150,7 +150,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.$router.push('/dashboard');
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -3,6 +3,6 @@ export default {
|
|||
async created() {
|
||||
await this.$store.dispatch('auth/logout');
|
||||
this.$router.replace('/login');
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -74,7 +74,7 @@ export default {
|
|||
username: null,
|
||||
password: null,
|
||||
rePassword: null,
|
||||
isLoading: false,
|
||||
isLoading: false
|
||||
};
|
||||
},
|
||||
computed: mapState(['config', 'auth']),
|
||||
|
@ -98,7 +98,7 @@ export default {
|
|||
try {
|
||||
const response = await this.$store.dispatch('auth/register', {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
password: this.password
|
||||
});
|
||||
|
||||
this.$notifier.success(response.message);
|
||||
|
@ -109,7 +109,7 @@ export default {
|
|||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -14,12 +14,12 @@ export default function ({ $axios, store }) {
|
|||
if (error.response?.data?.message) {
|
||||
store.dispatch('alert/set', {
|
||||
text: error.response.data.message,
|
||||
error: true,
|
||||
error: true
|
||||
});
|
||||
} else {
|
||||
store.dispatch('alert/set', {
|
||||
text: `[AXIOS]: ${error.message}`,
|
||||
error: true,
|
||||
error: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@ Vue.prototype.$search = {
|
|||
do: async (term, field) => {
|
||||
const results = await search.search(term, { field });
|
||||
return results;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,18 +8,18 @@ export default ({ store }, inject) => {
|
|||
|
||||
store.commit('alert/set', {
|
||||
message: response?.message ?? 'Executed sucesfully',
|
||||
type: AlertTypes.SUCCESS,
|
||||
type: AlertTypes.SUCCESS
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
store.commit('alert/set', {
|
||||
message: e.message,
|
||||
type: AlertTypes.ERROR,
|
||||
type: AlertTypes.ERROR
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -20,6 +20,6 @@ export default ({ store }, inject) => {
|
|||
error(message, snackbar) {
|
||||
this.showMessage({ message, type: AlertTypes.ERROR, snackbar });
|
||||
},
|
||||
types: AlertTypes,
|
||||
types: AlertTypes
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,5 +3,5 @@ import VueIsYourPasswordSafe from 'vue-isyourpasswordsafe';
|
|||
|
||||
Vue.use(VueIsYourPasswordSafe, {
|
||||
minLength: 6,
|
||||
maxLength: 64,
|
||||
maxLength: 64
|
||||
});
|
||||
|
|
|
@ -4,5 +4,5 @@ import VueTimeago from 'vue-timeago';
|
|||
Vue.use(VueTimeago, {
|
||||
name: 'timeago',
|
||||
locale: 'en-US',
|
||||
locales: { 'en-US': require('vue-timeago/locales/en-US.json') },
|
||||
locales: { 'en-US': require('vue-timeago/locales/en-US.json') }
|
||||
});
|
||||
|
|
|
@ -8,10 +8,10 @@ export const state = () => ({
|
|||
editedAt: null,
|
||||
apiKeyEditedAt: null,
|
||||
isAdmin: null,
|
||||
files: [],
|
||||
files: []
|
||||
},
|
||||
file: {},
|
||||
settings: {},
|
||||
settings: {}
|
||||
});
|
||||
|
||||
export const actions = {
|
||||
|
@ -82,7 +82,7 @@ export const actions = {
|
|||
const response = await this.$axios.$post('service/restart');
|
||||
|
||||
return response;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -118,5 +118,5 @@ export const mutations = {
|
|||
state.user.isAdmin = isAdmin;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,12 +5,12 @@ export const state = () => ({
|
|||
isListLoading: false,
|
||||
albumDetails: {},
|
||||
expandedAlbums: [],
|
||||
tinyDetails: [],
|
||||
tinyDetails: []
|
||||
});
|
||||
|
||||
export const getters = {
|
||||
isExpanded: (state) => (id) => state.expandedAlbums.indexOf(id) > -1,
|
||||
getDetails: (state) => (id) => state.albumDetails[id] || {},
|
||||
getDetails: (state) => (id) => state.albumDetails[id] || {}
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
|
@ -28,8 +28,8 @@ export const actions = {
|
|||
commit('setDetails', {
|
||||
id: albumId,
|
||||
details: {
|
||||
links: response.links,
|
||||
},
|
||||
links: response.links
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
|
@ -66,7 +66,7 @@ export const actions = {
|
|||
const response = await this.$axios.$post('album/link/edit', {
|
||||
identifier: linkOpts.identifier,
|
||||
enableDownload: linkOpts.enableDownload,
|
||||
enabled: linkOpts.enabled,
|
||||
enabled: linkOpts.enabled
|
||||
});
|
||||
|
||||
commit('updateAlbumLinkOpts', { albumId, linkOpts: response.data });
|
||||
|
@ -86,7 +86,7 @@ export const actions = {
|
|||
commit('setTinyDetails', response);
|
||||
|
||||
return response;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -113,7 +113,7 @@ export const mutations = {
|
|||
},
|
||||
updateAlbumLinkOpts(state, { albumId, linkOpts }) {
|
||||
const foundIndex = state.albumDetails[albumId].links.findIndex(
|
||||
({ identifier }) => identifier === linkOpts.identifier,
|
||||
({ identifier }) => identifier === linkOpts.identifier
|
||||
);
|
||||
const link = state.albumDetails[albumId].links[foundIndex];
|
||||
state.albumDetails[albumId].links[foundIndex] = { ...link, ...linkOpts };
|
||||
|
@ -132,5 +132,5 @@ export const mutations = {
|
|||
},
|
||||
setTinyDetails(state, { albums }) {
|
||||
state.tinyDetails = albums;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import AlertTypes from '~/constants/alertTypes';
|
|||
const getDefaultState = () => ({
|
||||
message: null,
|
||||
type: null,
|
||||
snackbar: false,
|
||||
snackbar: false
|
||||
});
|
||||
|
||||
export const state = getDefaultState;
|
||||
|
@ -18,7 +18,7 @@ export const actions = {
|
|||
},
|
||||
clear({ commit }) {
|
||||
commit('clear');
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -29,5 +29,5 @@ export const mutations = {
|
|||
},
|
||||
clear(state) {
|
||||
Object.assign(state, getDefaultState());
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,9 +3,9 @@ const getDefaultState = () => ({
|
|||
user: {
|
||||
id: null,
|
||||
isAdmin: false,
|
||||
username: null,
|
||||
username: null
|
||||
},
|
||||
token: null,
|
||||
token: null
|
||||
});
|
||||
|
||||
export const state = getDefaultState;
|
||||
|
@ -13,7 +13,7 @@ export const state = getDefaultState;
|
|||
export const getters = {
|
||||
isLoggedIn: (state) => state.loggedIn,
|
||||
getApiKey: (state) => state.user?.apiKey,
|
||||
getToken: (state) => state.token,
|
||||
getToken: (state) => state.token
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
|
@ -37,7 +37,7 @@ export const actions = {
|
|||
async register(_, { username, password }) {
|
||||
return this.$axios.$post('auth/register', {
|
||||
username,
|
||||
password,
|
||||
password
|
||||
});
|
||||
},
|
||||
async fetchCurrentUser({ commit, dispatch }) {
|
||||
|
@ -52,7 +52,7 @@ export const actions = {
|
|||
try {
|
||||
const response = await this.$axios.$post('user/password/change', {
|
||||
password,
|
||||
newPassword,
|
||||
newPassword
|
||||
});
|
||||
|
||||
return response;
|
||||
|
@ -76,7 +76,7 @@ export const actions = {
|
|||
},
|
||||
logout({ commit }) {
|
||||
commit('logout');
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -102,5 +102,5 @@ export const mutations = {
|
|||
this.$cookies.remove('token', { path: '/' });
|
||||
// reset state to default
|
||||
Object.assign(state, getDefaultState());
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,11 +8,11 @@ export const state = () => ({
|
|||
chunkSize: 90,
|
||||
maxLinksPerAlbum: 5,
|
||||
publicMode: false,
|
||||
userAccounts: false,
|
||||
userAccounts: false
|
||||
});
|
||||
|
||||
export const mutations = {
|
||||
set(state, config) {
|
||||
Object.assign(state, config);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,14 +6,14 @@ export const getDefaultState = () => ({
|
|||
pagination: {
|
||||
page: 1,
|
||||
limit: 30,
|
||||
totalFiles: 0,
|
||||
totalFiles: 0
|
||||
},
|
||||
search: '',
|
||||
albumName: null,
|
||||
albumDownloadEnabled: false,
|
||||
fileExtraInfoMap: {}, // information about the selected file
|
||||
fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in
|
||||
fileTagsMap: {}, // map of file ids with a list of tag objects for the file
|
||||
fileTagsMap: {} // map of file ids with a list of tag objects for the file
|
||||
});
|
||||
|
||||
export const state = getDefaultState;
|
||||
|
@ -23,7 +23,7 @@ export const getters = {
|
|||
getFetchedCount: ({ files }) => files.length,
|
||||
shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit,
|
||||
getLimit: ({ pagination }) => pagination.limit,
|
||||
getName: ({ name }) => name,
|
||||
getName: ({ name }) => name
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
|
@ -50,7 +50,7 @@ export const actions = {
|
|||
page = page || 1;
|
||||
|
||||
const response = await this.$axios.$get(`album/${id}/full`, {
|
||||
params: { limit: state.pagination.limit, page },
|
||||
params: { limit: state.pagination.limit, page }
|
||||
});
|
||||
|
||||
commit('setFilesAndMeta', { ...response, page });
|
||||
|
@ -113,7 +113,7 @@ export const actions = {
|
|||
const response = await this.$axios.$get(`search/?q=${encodeURI(q)}${optionalAlbum}`);
|
||||
|
||||
return response;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -121,7 +121,7 @@ export const mutations = {
|
|||
state.isLoading = true;
|
||||
},
|
||||
setFilesAndMeta(state, {
|
||||
files, name, page, count, downloadEnabled,
|
||||
files, name, page, count, downloadEnabled
|
||||
}) {
|
||||
state.files = files || [];
|
||||
state.albumName = name ?? null;
|
||||
|
@ -174,5 +174,5 @@ export const mutations = {
|
|||
},
|
||||
resetState(state) {
|
||||
Object.assign(state, getDefaultState());
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue