diff --git a/assets/components/releases/release.vue b/assets/components/releases/release.vue index 4e857ef2..7a98c30e 100644 --- a/assets/components/releases/release.vue +++ b/assets/components/releases/release.vue @@ -55,14 +55,14 @@ v-show="me && isStashed" icon="heart7" class="stash stashed noselect" - @click="unstashScene" + @click="unstashRelease" /> @@ -251,18 +251,20 @@ async function fetchRelease(scroll = true) { } } -async function stashScene() { - this.$store.dispatch('stashScene', { +async function stashRelease() { + this.$store.dispatch(this.$route.name === 'movie' ? 'stashMovie' : 'stashRelease', { sceneId: this.release.id, + movieId: this.release.id, stashId: this.$store.getters.favorites.id, }); this.fetchRelease(false); } -async function unstashScene() { - this.$store.dispatch('unstashScene', { +async function unstashRelease() { + this.$store.dispatch(this.$route.name === 'movie' ? 'unstashMovie' : 'unstashRelease', { sceneId: this.release.id, + movieId: this.release.id, stashId: this.$store.getters.favorites.id, }); @@ -321,8 +323,8 @@ export default { mounted: fetchRelease, methods: { fetchRelease, - stashScene, - unstashScene, + stashRelease, + unstashRelease, }, }; diff --git a/assets/js/releases/actions.js b/assets/js/releases/actions.js index b5d06ff1..a32b9af4 100644 --- a/assets/js/releases/actions.js +++ b/assets/js/releases/actions.js @@ -138,7 +138,11 @@ function initReleasesActions(store, router) { // const release = await get(`/releases/${releaseId}`); const { movie } = await graphql(` - query Movie($movieId: Int!) { + query Movie( + $movieId: Int! + $hasAuth: Boolean! + $userId: Int + ) { movie(id: $movieId) { id title @@ -232,10 +236,27 @@ function initReleasesActions(store, router) { hasLogo } } + stashes: stashesMovies( + filter: { + stash: { + userId: { + equalTo: $userId + } + } + } + ) @include(if: $hasAuth) { + stash { + id + name + slug + } + } } } `, { movieId: Number(movieId), + hasAuth: !!store.state.auth.user, + userId: store.state.auth.user?.id, }); if (!movie) { diff --git a/assets/js/stashes/actions.js b/assets/js/stashes/actions.js index 4d3dbee4..16ab1a60 100644 --- a/assets/js/stashes/actions.js +++ b/assets/js/stashes/actions.js @@ -17,11 +17,21 @@ function initStashesActions(_store, _router) { await del(`/stashes/${stashId}/scenes/${sceneId}`); } + async function stashMovie(context, { movieId, stashId }) { + await post(`/stashes/${stashId}/movies`, { movieId }); + } + + async function unstashMovie(context, { movieId, stashId }) { + await del(`/stashes/${stashId}/movies/${movieId}`); + } + return { stashActor, stashScene, + stashMovie, unstashActor, unstashScene, + unstashMovie, }; } diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index 6de2caba..61f368f4 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -1054,7 +1054,8 @@ exports.up = knex => Promise.resolve() table.integer('user_id') .references('id') - .inTable('users'); + .inTable('users') + .onDelete('cascade'); table.string('name') .notNullable(); @@ -1074,27 +1075,48 @@ exports.up = knex => Promise.resolve() table.integer('stash_id') .notNullable() .references('id') - .inTable('stashes'); + .inTable('stashes') + .onDelete('cascade'); table.integer('scene_id') .notNullable() .references('id') - .inTable('releases'); + .inTable('releases') + .onDelete('cascade'); table.unique(['stash_id', 'scene_id']); table.string('comment'); })) + .then(() => knex.schema.createTable('stashes_movies', (table) => { + table.integer('stash_id') + .notNullable() + .references('id') + .inTable('stashes') + .onDelete('cascade'); + + table.integer('movie_id') + .notNullable() + .references('id') + .inTable('movies') + .onDelete('cascade'); + + table.unique(['stash_id', 'movie_id']); + + table.string('comment'); + })) .then(() => knex.schema.createTable('stashes_actors', (table) => { table.integer('stash_id') .notNullable() .references('id') - .inTable('stashes'); + .inTable('stashes') + .onDelete('cascade'); table.integer('actor_id') .notNullable() .references('id') - .inTable('actors'); + .inTable('actors') + .onDelete('cascade'); table.unique(['stash_id', 'actor_id']); @@ -1304,6 +1326,7 @@ exports.up = knex => Promise.resolve() ALTER TABLE stashes ENABLE ROW LEVEL SECURITY; ALTER TABLE stashes_scenes ENABLE ROW LEVEL SECURITY; + ALTER TABLE stashes_movies ENABLE ROW LEVEL SECURITY; ALTER TABLE stashes_actors ENABLE ROW LEVEL SECURITY; CREATE POLICY stashes_policy_select ON stashes FOR SELECT USING (stashes.public OR stashes.user_id = current_user_id()); @@ -1319,6 +1342,14 @@ exports.up = knex => Promise.resolve() AND (stashes.user_id = current_user_id() OR stashes.public) )); + CREATE POLICY stashes_policy ON stashes_movies + USING (EXISTS ( + SELECT * + FROM stashes + WHERE stashes.id = stashes_movies.stash_id + AND (stashes.user_id = current_user_id() OR stashes.public) + )); + CREATE POLICY stashes_policy ON stashes_actors USING (EXISTS ( SELECT * @@ -1416,6 +1447,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style DROP TABLE IF EXISTS entities CASCADE; DROP TABLE IF EXISTS stashes_scenes CASCADE; + DROP TABLE IF EXISTS stashes_movies CASCADE; DROP TABLE IF EXISTS stashes_actors CASCADE; DROP TABLE IF EXISTS stashes CASCADE; diff --git a/public/img/tags/blowjob/cecilia_lion_wefuckblackgirls.jpeg b/public/img/tags/blowjob/cecilia_lion_wefuckblackgirls.jpeg new file mode 100644 index 00000000..89e71e1b Binary files /dev/null and b/public/img/tags/blowjob/cecilia_lion_wefuckblackgirls.jpeg differ diff --git a/public/img/tags/blowjob/lazy/cecilia_lion_wefuckblackgirls.jpeg b/public/img/tags/blowjob/lazy/cecilia_lion_wefuckblackgirls.jpeg new file mode 100644 index 00000000..3fd3ff19 Binary files /dev/null and b/public/img/tags/blowjob/lazy/cecilia_lion_wefuckblackgirls.jpeg differ diff --git a/public/img/tags/blowjob/thumbs/cecilia_lion_wefuckblackgirls.jpeg b/public/img/tags/blowjob/thumbs/cecilia_lion_wefuckblackgirls.jpeg new file mode 100644 index 00000000..a227c845 Binary files /dev/null and b/public/img/tags/blowjob/thumbs/cecilia_lion_wefuckblackgirls.jpeg differ diff --git a/public/img/tags/cum-in-mouth/lara_frost_legalporno.jpeg b/public/img/tags/cum-in-mouth/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..ee774e42 Binary files /dev/null and b/public/img/tags/cum-in-mouth/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/cum-in-mouth/lazy/lara_frost_legalporno.jpeg b/public/img/tags/cum-in-mouth/lazy/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..19370e22 Binary files /dev/null and b/public/img/tags/cum-in-mouth/lazy/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/cum-in-mouth/thumbs/lara_frost_legalporno.jpeg b/public/img/tags/cum-in-mouth/thumbs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..0992cf79 Binary files /dev/null and b/public/img/tags/cum-in-mouth/thumbs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/dp/lara_frost_legalporno.jpeg b/public/img/tags/dp/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..6e27ebf0 Binary files /dev/null and b/public/img/tags/dp/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/dp/lazy/lara_frost_legalporno.jpeg b/public/img/tags/dp/lazy/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..dd99dfe6 Binary files /dev/null and b/public/img/tags/dp/lazy/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/dp/thumbs/lara_frost_legalporno.jpeg b/public/img/tags/dp/thumbs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..63fae0b0 Binary files /dev/null and b/public/img/tags/dp/thumbs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/enhanced-boobs/lara_frost_legalporno.jpeg b/public/img/tags/enhanced-boobs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..cc5f818a Binary files /dev/null and b/public/img/tags/enhanced-boobs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/enhanced-boobs/lazy/lara_frost_legalporno.jpeg b/public/img/tags/enhanced-boobs/lazy/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..863dd923 Binary files /dev/null and b/public/img/tags/enhanced-boobs/lazy/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/enhanced-boobs/thumbs/lara_frost_legalporno.jpeg b/public/img/tags/enhanced-boobs/thumbs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..108c9db2 Binary files /dev/null and b/public/img/tags/enhanced-boobs/thumbs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/flexible/lara_frost_legalporno.jpeg b/public/img/tags/flexible/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..2fe2b709 Binary files /dev/null and b/public/img/tags/flexible/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/flexible/lazy/lara_frost_legalporno.jpeg b/public/img/tags/flexible/lazy/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..e9367610 Binary files /dev/null and b/public/img/tags/flexible/lazy/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/flexible/thumbs/lara_frost_legalporno.jpeg b/public/img/tags/flexible/thumbs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..d212956b Binary files /dev/null and b/public/img/tags/flexible/thumbs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/gangbang/7.jpeg b/public/img/tags/gangbang/7.jpeg index 54bb0e33..0ee32193 100644 Binary files a/public/img/tags/gangbang/7.jpeg and b/public/img/tags/gangbang/7.jpeg differ diff --git a/public/img/tags/gangbang/poster.jpeg b/public/img/tags/gangbang/kristen_scott_julesjordan.jpeg similarity index 100% rename from public/img/tags/gangbang/poster.jpeg rename to public/img/tags/gangbang/kristen_scott_julesjordan.jpeg diff --git a/public/img/tags/gangbang/lara_frost_legalporno.jpeg b/public/img/tags/gangbang/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..b2d287f9 Binary files /dev/null and b/public/img/tags/gangbang/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/gangbang/lara_frost_legalporno_1.jpeg b/public/img/tags/gangbang/lara_frost_legalporno_1.jpeg new file mode 100644 index 00000000..6047d27a Binary files /dev/null and b/public/img/tags/gangbang/lara_frost_legalporno_1.jpeg differ diff --git a/public/img/tags/gangbang/lara_frost_legalporno_a.jpeg b/public/img/tags/gangbang/lara_frost_legalporno_a.jpeg new file mode 100644 index 00000000..19a796be Binary files /dev/null and b/public/img/tags/gangbang/lara_frost_legalporno_a.jpeg differ diff --git a/public/img/tags/gangbang/lazy/7.jpeg b/public/img/tags/gangbang/lazy/7.jpeg index 946dd992..c059ef9b 100644 Binary files a/public/img/tags/gangbang/lazy/7.jpeg and b/public/img/tags/gangbang/lazy/7.jpeg differ diff --git a/public/img/tags/gangbang/lazy/kristen_scott_julesjordan.jpeg b/public/img/tags/gangbang/lazy/kristen_scott_julesjordan.jpeg new file mode 100644 index 00000000..de640787 Binary files /dev/null and b/public/img/tags/gangbang/lazy/kristen_scott_julesjordan.jpeg differ diff --git a/public/img/tags/gangbang/lazy/lara_frost_legalporno.jpeg b/public/img/tags/gangbang/lazy/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..a765d086 Binary files /dev/null and b/public/img/tags/gangbang/lazy/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/gangbang/lazy/lara_frost_legalporno_1.jpeg b/public/img/tags/gangbang/lazy/lara_frost_legalporno_1.jpeg new file mode 100644 index 00000000..7d24ebe0 Binary files /dev/null and b/public/img/tags/gangbang/lazy/lara_frost_legalporno_1.jpeg differ diff --git a/public/img/tags/gangbang/lazy/lara_frost_legalporno_a.jpeg b/public/img/tags/gangbang/lazy/lara_frost_legalporno_a.jpeg new file mode 100644 index 00000000..1d86fc18 Binary files /dev/null and b/public/img/tags/gangbang/lazy/lara_frost_legalporno_a.jpeg differ diff --git a/public/img/tags/gangbang/lazy/silvia_soprano_legalporno.jpeg b/public/img/tags/gangbang/lazy/silvia_soprano_legalporno.jpeg new file mode 100644 index 00000000..11462a52 Binary files /dev/null and b/public/img/tags/gangbang/lazy/silvia_soprano_legalporno.jpeg differ diff --git a/public/img/tags/gangbang/6.jpeg b/public/img/tags/gangbang/silvia_soprano_legalporno.jpeg similarity index 100% rename from public/img/tags/gangbang/6.jpeg rename to public/img/tags/gangbang/silvia_soprano_legalporno.jpeg diff --git a/public/img/tags/gangbang/thumbs/7.jpeg b/public/img/tags/gangbang/thumbs/7.jpeg index 0638c185..732d3ec2 100644 Binary files a/public/img/tags/gangbang/thumbs/7.jpeg and b/public/img/tags/gangbang/thumbs/7.jpeg differ diff --git a/public/img/tags/gangbang/thumbs/kristen_scott_julesjordan.jpeg b/public/img/tags/gangbang/thumbs/kristen_scott_julesjordan.jpeg new file mode 100644 index 00000000..292eb72f Binary files /dev/null and b/public/img/tags/gangbang/thumbs/kristen_scott_julesjordan.jpeg differ diff --git a/public/img/tags/gangbang/thumbs/lara_frost_legalporno.jpeg b/public/img/tags/gangbang/thumbs/lara_frost_legalporno.jpeg new file mode 100644 index 00000000..f64432f3 Binary files /dev/null and b/public/img/tags/gangbang/thumbs/lara_frost_legalporno.jpeg differ diff --git a/public/img/tags/gangbang/thumbs/lara_frost_legalporno_1.jpeg b/public/img/tags/gangbang/thumbs/lara_frost_legalporno_1.jpeg new file mode 100644 index 00000000..2a546505 Binary files /dev/null and b/public/img/tags/gangbang/thumbs/lara_frost_legalporno_1.jpeg differ diff --git a/public/img/tags/gangbang/thumbs/lara_frost_legalporno_a.jpeg b/public/img/tags/gangbang/thumbs/lara_frost_legalporno_a.jpeg new file mode 100644 index 00000000..57535105 Binary files /dev/null and b/public/img/tags/gangbang/thumbs/lara_frost_legalporno_a.jpeg differ diff --git a/public/img/tags/gangbang/thumbs/silvia_soprano_legalporno.jpeg b/public/img/tags/gangbang/thumbs/silvia_soprano_legalporno.jpeg new file mode 100644 index 00000000..8fb6e946 Binary files /dev/null and b/public/img/tags/gangbang/thumbs/silvia_soprano_legalporno.jpeg differ diff --git a/public/img/tags/toy-anal/ember_snow_jane_wilde_lesbianx.jpeg b/public/img/tags/toy-anal/ember_snow_jane_wilde_lesbianx.jpeg new file mode 100644 index 00000000..b57e9205 Binary files /dev/null and b/public/img/tags/toy-anal/ember_snow_jane_wilde_lesbianx.jpeg differ diff --git a/public/img/tags/toy-anal/lazy/ember_snow_jane_wilde_lesbianx.jpeg b/public/img/tags/toy-anal/lazy/ember_snow_jane_wilde_lesbianx.jpeg new file mode 100644 index 00000000..98ec53da Binary files /dev/null and b/public/img/tags/toy-anal/lazy/ember_snow_jane_wilde_lesbianx.jpeg differ diff --git a/public/img/tags/toy-anal/thumbs/ember_snow_jane_wilde_lesbianx.jpeg b/public/img/tags/toy-anal/thumbs/ember_snow_jane_wilde_lesbianx.jpeg new file mode 100644 index 00000000..98d8593e Binary files /dev/null and b/public/img/tags/toy-anal/thumbs/ember_snow_jane_wilde_lesbianx.jpeg differ diff --git a/seeds/00_tags.js b/seeds/00_tags.js index 9d274eea..5b8ebc97 100644 --- a/seeds/00_tags.js +++ b/seeds/00_tags.js @@ -98,7 +98,7 @@ const tags = [ { name: 'airtight', slug: 'airtight', - description: 'Stuffing one cock in her ass, one in her pussy, and one in her mouth, filling all of her penetrable holes and sealing her airtight like a figurative balloon. In other words, simultaneously getting [double penetrated](/tag/dp), and giving a [blowjob](/tag/blowjob) or getting [facefucked](/tag/facefuck). Being airtight implies being [gangbanged](/tag/gangbang).', /* eslint-disable-line max-len */ + description: 'Stuffing one cock in your ass, one in your pussy, and one in your mouth, filling up all of your penetrable holes and getting sealed airtight like a figurative balloon. In other words, simultaneously getting [double penetrated](/tag/dp), and giving a [blowjob](/tag/blowjob) or getting [facefucked](/tag/facefucking). Being airtight implies being [gangbanged](/tag/gangbang).', /* eslint-disable-line max-len */ priority: 9, group: 'penetration', }, @@ -242,13 +242,14 @@ const tags = [ name: 'blowjob', slug: 'blowjob', priority: 5, + description: 'Taking a dick in your mouth, sucking, licking and kissing it, often while giving a [handjob](/tag/handjob). You may slide it all the way [down your throat](/tag/deepthroat), or let them [fuck your face](/tag/facefucking).', group: 'oral', }, { name: 'blowbang', slug: 'blowbang', priority: 9, - description: 'Pleasuring a gang of three or more cocks by sucking and jerking off as many cocks as they can, often getting [facefucked](/tag/facefuck), groped and rubbed out, and followed by a [bukkake](/tag/bukkake). If they are getting fucked, it is a [gangbang](/tag/gangbang).', + description: 'Pleasuring a gang of three or more cocks by sucking and jerking off as many cocks as you can, often getting [facefucked](/tag/facefucking), groped and rubbed out, and followed by a [bukkake](/tag/bukkake). If you are also getting fucked, it is a [gangbang](/tag/gangbang).', group: 'group', }, { @@ -388,13 +389,14 @@ const tags = [ name: 'deepthroat', slug: 'deepthroat', priority: 6, + description: 'Shoving a cock down your throat during a [blowjob](/tag/blowjob) or [facefuck](/tag/facefucking), giving them a tight sensation while showing off your skills. Without practice, their cock hitting the back of your mouth may make you [gag](/tag/gagging).', group: 'oral', }, { name: 'double penetration', slug: 'dp', priority: 9, - description: 'Fucking two cocks at once, with one in her ass, and one in her pussy. If she has another cock in her mouth, she is [airtight](/tag/airtight).', + description: 'Getting your [ass](/tag/anal) and pussy fucked at the same time. If you take another cock in your mouth, you are [airtight](/tag/airtight).', group: 'penetration', }, { @@ -450,6 +452,7 @@ const tags = [ name: 'facefucking', slug: 'facefucking', priority: 7, + description: 'A [blowjob](/tag/blowjob) where you give up control, and let them fuck your mouth and [throat](/tag/deepthroat) as if it\'s your pussy.', group: 'oral', }, { @@ -487,6 +490,10 @@ const tags = [ name: 'fisting DP', slug: 'fisting-dp', }, + { + name: 'flexible', + slug: 'flexible', + }, { name: 'MFF threesome', slug: 'mff', diff --git a/seeds/04_media.js b/seeds/04_media.js index 0a2969a5..6c145a59 100644 --- a/seeds/04_media.js +++ b/seeds/04_media.js @@ -650,9 +650,10 @@ const tagMedia = [ ['blowbang', 1, 'Nicole Black in GIO1680', 'legalporno'], ['blowjob', 1, 'Kylie Page in "Stepsis Gives Soapy Handjob In Shower"', 'spyfam'], ['blowjob', 4, 'Chloe Cherry in "Chloe\'s Big Anal"', 'darkx'], + ['blowjob', 'cecilia_lion_wefuckblackgirls', 'Cecilia Lion in "Cecilia Lion\'s Second Appearance"', 'wefuckblackgirls'], + ['blowjob', 0, 'Adriana Chechik in "The Dinner Party"', 'realwifestories'], ['blowjob', 5, 'Kaylynn', 'mommyblowsbest'], ['blowjob', 'azul_hermosa_realitykings', 'Azul Hermosa and Scott Nails in "Diva For A Day"', 'brazzers'], - ['blowjob', 0, 'Adriana Chechik in "The Dinner Party"', 'realwifestories'], ['blowjob', 3, 'Rose Valie', 'handsonhardcore'], ['blowjob', 2, 'Luna Kitsuen in "Gag Reflex"', 'evilangel'], ['bondage', 0, 'Veronica Leal', 'herlimit'], @@ -675,6 +676,7 @@ const tagMedia = [ ['cum-in-mouth', 5, 'Emma Hix in "A Big Dick"', 'darkx'], ['cum-in-mouth', 4, 'Vanna Bardot and Isiah Maxwell in "Vanna Craves Isiah\'s Cock!"', 'darkx'], ['cum-in-mouth', 2, 'Jaye Summers in "Double The Cum"', 'hardx'], + ['cum-in-mouth', 'lara_frost_legalporno', 'Lara Frost in NRX059', 'legalporno'], ['cum-in-mouth', 0, 'Vina Sky and Avi Love', 'hardx'], ['cum-on-boobs', 1, 'Kylie Page in "Melt In Your Mouth"', 'twistyshard'], ['cum-on-boobs', 0, 'Alessandra Jane', 'private'], @@ -746,6 +748,7 @@ const tagMedia = [ ['dp', 3, 'Hime Marie in AA047', 'legalporno'], ['dp', 2, 'Megan Rain in "DP Masters 4"', 'julesjordan'], ['dp', 6, 'Kira Noir', 'hardx'], + ['dp', 'lara_frost_legalporno', 'Lara Frost in NRX070', 'legalporno'], ['dp', 5, 'Lana Rhoades in "Gangbang Me 3"', 'hardx'], ['dp', 'zaawaadi_roccosiffredi', 'Zaawaadi in "My Name Is Zaawaadi"', 'roccosiffredi'], ['dp', 7, 'Chloe Lamour in "DP Masters 7"', 'julesjordan'], @@ -771,6 +774,7 @@ const tagMedia = [ ['facial', 'hope_howell_manojob', 'Hope Howell in "Super Slutty Step-Daugher"', 'manojob'], ['facial', 2, 'Ashly Anderson', 'hookuphotshot'], ['facial', 4, 'Kendra Heart', 'facialsforever'], + ['flexible', 'lara_frost_legalporno', 'Lara Frost in NRX059', 'legalporno'], ['enhanced-boobs', 7, 'Charley Atwell', 'icandigirls'], ['enhanced-boobs', 14, 'Rikki Six', 'dreamdolls'], ['enhanced-boobs', 2, 'Gia Milana in "Hot Anal Latina"', 'hardx'], @@ -787,7 +791,8 @@ const tagMedia = [ ['enhanced-boobs', '23d', 'Lulu Sex Bomb in "Tropical Touch"'], ['enhanced-boobs', 22, 'Sakura Sena'], ['enhanced-boobs', 'mareeva_trudy_photodromm_1', 'Mareeva and Trudy', 'photodromm'], - ['enhanced-boobs', 'shawna_lenee_inthecrack_1', 'Shawna Lenee', 'inthecrack'], + ['enhanced-boobs', 'lara_frost_legalporno', 'Lara Frost in NRX059', 'legalporno'], + ['enhanced-boobs', 'shawna_lenee_inthecrack_3', 'Shawna Lenee', 'inthecrack'], ['enhanced-boobs', 16, 'Marsha May in "Once You Go Black 7"', 'julesjordan'], ['enhanced-boobs', 'azul_hermosa_pornstarslikeitbig', 'Azul Hermosa in "She Likes Rough Quickies"', 'pornstarslikeitbig'], ['enhanced-boobs', 21, 'Emelie Ekström'], @@ -814,10 +819,10 @@ const tagMedia = [ ['fisting', 0, 'Abella Danger and Karma Rx in "Neon Dreaming"', 'brazzers'], ['fisting-dp', 0, 'Janice Griffith and Veronica Avluv in "The Nymphomaniac\'s Apprentice', 'theupperfloor'], ['gangbang', 5, 'Carter Cruise\'s first gangbang in "Slut Puppies 9"', 'julesjordan'], - ['gangbang', 'poster', 'Kristen Scott in "Interracial Gangbang!"', 'julesjordan'], - ['gangbang', 7, 'Alexa Flexy in GL376'], + ['gangbang', 'kristen_scott_julesjordan', 'Kristen Scott in "Interracial Gangbang!"', 'julesjordan'], + ['gangbang', 'lara_frost_legalporno_1', 'Lara Frost in NRX070', 'legalporno'], + ['gangbang', 7, 'Alexa Flexy in GL376', 'legalporno'], ['gangbang', 0, '"4 On 1 Gangbangs"', 'doghousedigital'], - ['gangbang', 6, 'Silvia Soprano in GIO1580', 'legalporno'], ['gangbang', 4, 'Marley Brinx in "The Gangbang of Marley Brinx"', 'julesjordan'], ['gangbang', 1, 'Ginger Lynn in "Gangbang Mystique", a photoset shot by Suze Randall, 1984. Depicting a woman \'airtight\' pushed the boundaries of pornography at the time.'], ['gaping', 1, 'Vina Sky in "Vina Sky Does Anal"', 'hardx'], @@ -914,8 +919,9 @@ const tagMedia = [ ['titty-fucking', 4, 'Set 5532', 'tugjobs'], ['titty-fucking', 3, 'Anna Bell Peaks in "Ringing Her Bell"', 'milfvr'], ['titty-fucking', 1, 'Chloe Lamour', 'ddfbusty'], - ['toy-anal', 1, 'Nina North and Cassidy Klein in "Nina\'s First Lesbian Anal"', 'lesbianx'], ['toy-anal', 3, 'Kelly and Leona in "Sleeping Over"', 'lezcuties'], + ['toy-anal', 'ember_snow_jane_wilde_lesbianx', 'Ember Snow and Jane Wilde in "Ember\'s Wilde Ride"', 'lesbianx'], + ['toy-anal', 1, 'Nina North and Cassidy Klein in "Nina\'s First Lesbian Anal"', 'lesbianx'], ['toy-anal', 2, 'Denise, Irina and Laki in "Sexy Slumber"', 'lezcuties'], ['toy-anal', 0, 'Kira Noir in 1225', 'inthecrack'], ['toy-dp', 1, 'Krissy Lynn and London River in "Lesbian DP Workout"', 'lesbianx'], diff --git a/src/auth.js b/src/auth.js index 021a7a26..bf508fd6 100644 --- a/src/auth.js +++ b/src/auth.js @@ -67,7 +67,7 @@ async function signup(credentials) { const hashedPassword = (await scrypt(credentials.password, salt, 64)).toString('hex'); const storedPassword = `${salt}/${hashedPassword}`; - const [user] = await knex('users') + const [userId] = await knex('users') .insert({ username: credentials.username, email: credentials.email, @@ -76,13 +76,13 @@ async function signup(credentials) { .returning('id'); await knex('stashes').insert({ - user_id: user.id, + user_id: userId, name: 'Favorites', slug: 'favorites', public: false, }); - return fetchUser(user.id); + return fetchUser(userId); } module.exports = { diff --git a/src/stashes.js b/src/stashes.js index a61fffdc..8f10276e 100644 --- a/src/stashes.js +++ b/src/stashes.js @@ -4,6 +4,10 @@ const knex = require('./knex'); const { HttpError } = require('./errors'); function curateStash(stash) { + if (!stash) { + return null; + } + const curatedStash = { id: stash.id, name: stash.name, @@ -52,12 +56,22 @@ async function stashScene(sceneId, stashId, sessionUser) { }); } +async function stashMovie(movieId, stashId, sessionUser) { + const stash = await fetchStash(stashId, sessionUser); + + await knex('stashes_movies') + .insert({ + stash_id: stash.id, + movie_id: movieId, + }); +} + async function unstashActor(actorId, stashId, sessionUser) { await knex .from('stashes_actors AS deletable') .where('deletable.actor_id', actorId) .where('deletable.stash_id', stashId) - .whereExists(knex('stashes_actors') // verify user owns this stash + .whereExists(knex('stashes_actors') // verify user owns this stash, complimentary to row-level security .leftJoin('stashes', 'stashes.id', 'stashes_actors.stash_id') .where('stashes_actors.stash_id', knex.raw('deletable.stash_id')) .where('stashes.user_id', sessionUser.id)) @@ -69,17 +83,31 @@ async function unstashScene(sceneId, stashId, sessionUser) { .from('stashes_scenes AS deletable') .where('deletable.scene_id', sceneId) .where('deletable.stash_id', stashId) - .whereExists(knex('stashes_scenes') // verify user owns this stash + .whereExists(knex('stashes_scenes') // verify user owns this stash, complimentary to row-level security .leftJoin('stashes', 'stashes.id', 'stashes_scenes.stash_id') .where('stashes_scenes.stash_id', knex.raw('deletable.stash_id')) .where('stashes.user_id', sessionUser.id)) .delete(); } +async function unstashMovie(movieId, stashId, sessionUser) { + await knex + .from('stashes_movies AS deletable') + .where('deletable.movie_id', movieId) + .where('deletable.stash_id', stashId) + .whereExists(knex('stashes_movies') // verify user owns this stash, complimentary to row-level security + .leftJoin('stashes', 'stashes.id', 'stashes_movies.stash_id') + .where('stashes_movies.stash_id', knex.raw('deletable.stash_id')) + .where('stashes.user_id', sessionUser.id)) + .delete(); +} + module.exports = { curateStash, stashActor, stashScene, + stashMovie, unstashScene, unstashActor, + unstashMovie, }; diff --git a/src/users.js b/src/users.js index c6ac9dcd..b70ed4e1 100644 --- a/src/users.js +++ b/src/users.js @@ -18,7 +18,7 @@ function curateUser(user) { identityVerified: user.identity_verified, ability, createdAt: user.created_at, - stashes: user.stashes?.map(stash => curateStash(stash)) || [], + stashes: user.stashes?.filter(Boolean).map(stash => curateStash(stash)) || [], }; return curatedUser; @@ -26,7 +26,7 @@ function curateUser(user) { async function fetchUser(userId, raw) { const user = await knex('users') - .select(knex.raw('users.*, users_roles.abilities as role_abilities, json_agg(stashes) as stashes')) + .select(knex.raw('users.*, users_roles.abilities as role_abilities, COALESCE(json_agg(stashes) FILTER (WHERE stashes.id IS NOT NULL), \'[]\') as stashes')) .modify((builder) => { if (typeof userId === 'number') { builder.where('users.id', userId); diff --git a/src/web/error.js b/src/web/error.js index 736782cb..b058768d 100644 --- a/src/web/error.js +++ b/src/web/error.js @@ -1,10 +1,15 @@ 'use strict'; +const argv = require('../argv'); const logger = require('../logger')(__filename); function errorHandler(error, req, res, _next) { logger.warn(`Failed to fulfill request to ${req.path}: ${error.message}`); + if (argv.debug) { + logger.error(error); + } + if (error.httpCode) { res.status(error.httpCode).send(error.message); diff --git a/src/web/server.js b/src/web/server.js index 431b208a..d09366e1 100644 --- a/src/web/server.js +++ b/src/web/server.js @@ -46,8 +46,10 @@ const { const { stashActor, stashScene, + stashMovie, unstashActor, unstashScene, + unstashMovie, } = require('./stashes'); async function initServer() { @@ -83,9 +85,11 @@ async function initServer() { router.post('/api/stashes/:stashId/actors', stashActor); router.post('/api/stashes/:stashId/scenes', stashScene); + router.post('/api/stashes/:stashId/movies', stashMovie); router.delete('/api/stashes/:stashId/actors/:actorId', unstashActor); router.delete('/api/stashes/:stashId/scenes/:sceneId', unstashScene); + router.delete('/api/stashes/:stashId/movies/:movieId', unstashMovie); router.get('/api/scenes', fetchScenes); router.get('/api/scenes/:releaseId', fetchScene); diff --git a/src/web/stashes.js b/src/web/stashes.js index d9a7b00c..885961f1 100644 --- a/src/web/stashes.js +++ b/src/web/stashes.js @@ -1,6 +1,13 @@ 'use strict'; -const { stashActor, stashScene, unstashActor, unstashScene } = require('../stashes'); +const { + stashActor, + stashScene, + stashMovie, + unstashActor, + unstashScene, + unstashMovie, +} = require('../stashes'); async function stashActorApi(req, res) { await stashActor(req.body.actorId, req.params.stashId, req.session.user); @@ -14,6 +21,12 @@ async function stashSceneApi(req, res) { res.status(201).send(); } +async function stashMovieApi(req, res) { + await stashMovie(req.body.movieId, req.params.stashId, req.session.user); + + res.status(201).send(); +} + async function unstashActorApi(req, res) { await unstashActor(req.params.actorId, req.params.stashId, req.session.user); @@ -26,9 +39,17 @@ async function unstashSceneApi(req, res) { res.status(204).send(); } +async function unstashMovieApi(req, res) { + await unstashMovie(req.params.movieId, req.params.stashId, req.session.user); + + res.status(204).send(); +} + module.exports = { stashActor: stashActorApi, stashScene: stashSceneApi, + stashMovie: stashMovieApi, unstashActor: unstashActorApi, unstashScene: unstashSceneApi, + unstashMovie: unstashMovieApi, };