style(*): edit indents
This commit is contained in:
parent
c8e84c909e
commit
8f45dbe563
@ -1,6 +1,7 @@
|
|||||||
[*.*]
|
root = true
|
||||||
|
[*]
|
||||||
tab_width = 2
|
tab_width = 2
|
||||||
indent_size = 1
|
indent_size = 2
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
max_line_length = 160
|
max_line_length = 160
|
@ -2,25 +2,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
© Rockfic.com, since 2004. Rockfic.com is in no way associated with any
|
© Rockfic.com, since 2004. Rockfic.com is in no way associated with any band listed on this website. Rockfic.com is entertainment. All stories contained
|
||||||
band listed on this website. Rockfic.com is entertainment. All stories
|
on this site are fictional, which means that while the characters may be loosely based on the public personas of real people, the stories themselves are
|
||||||
contained on this site are fictional, which means that while the
|
completely ungrounded from reality and are in no way meant to reflect the private lives, actual practices, or activities of any persons named. Rockfic.com
|
||||||
characters may be loosely based on the public personas of real people, the
|
will remove a work of fiction if an individual named within requests its removal.<br />
|
||||||
stories themselves are completely ungrounded from reality and are in no
|
|
||||||
way meant to reflect the private lives, actual practices, or activities of
|
|
||||||
any persons named. Rockfic.com will remove a work of fiction if an
|
|
||||||
individual named within requests its removal.<br />
|
|
||||||
For site problems and/or bugs, contact
|
For site problems and/or bugs, contact
|
||||||
<a style="font-weight: bold" href="mailto:bugs@rockfic.com"
|
<a style="font-weight: bold" href="mailto:bugs@rockfic.com">bugs@rockfic.com</a>.<br />
|
||||||
>bugs@rockfic.com</a
|
|
||||||
>.<br />
|
|
||||||
For everything else, contact
|
For everything else, contact
|
||||||
<a href="mailto:admin@rockfic.com">admin@rockfic.com</a>.
|
<a href="mailto:admin@rockfic.com">admin@rockfic.com</a>.
|
||||||
</p>
|
</p>
|
||||||
<b>Copyright Notice</b><br />
|
<b>Copyright Notice</b><br />
|
||||||
All content on this site is copyright of its respective author. You may not,
|
All content on this site is copyright of its respective author. You may not, except with our express written permission, distribute or commercially exploit
|
||||||
except with our express written permission, distribute or commercially
|
the content. Nor may you transmit it or store it in any other website or other form of electronic retrieval system.
|
||||||
exploit the content. Nor may you transmit it or store it in any other
|
|
||||||
website or other form of electronic retrieval system.
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -30,11 +30,7 @@
|
|||||||
promote: !short,
|
promote: !short,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
messageApi.success(
|
messageApi.success(`User ${props.user?.username} is now ${short ? "an admin" : "a regular user"}.`);
|
||||||
`User ${props.user?.username} is now ${
|
|
||||||
short ? "an admin" : "a regular user"
|
|
||||||
}.`,
|
|
||||||
);
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showDemote.value = false;
|
showDemote.value = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@ -44,26 +40,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-space :size="10" direction="vertical">
|
<a-space :size="10" direction="vertical">
|
||||||
<div>
|
<div>
|
||||||
<a-descriptions
|
<a-descriptions :colon="false" :label-style="{ fontWeight: 'bold' }" :column="1">
|
||||||
:colon="false"
|
|
||||||
:label-style="{ fontWeight: 'bold' }"
|
|
||||||
:column="1"
|
|
||||||
>
|
|
||||||
<a-descriptions-item label="IP addresses">
|
<a-descriptions-item label="IP addresses">
|
||||||
<a-list :data-source="user?.ipLog">
|
<a-list :data-source="user?.ipLog">
|
||||||
<template #renderItem="{ item }">
|
<template #renderItem="{ item }">
|
||||||
{{ item.ip }}<br />
|
{{ item.ip }}<br />
|
||||||
<a-typography-title :level="5"
|
<a-typography-title :level="5">Other users with this IP:</a-typography-title>
|
||||||
>Other users with this IP:</a-typography-title
|
|
||||||
>
|
|
||||||
<div v-if="commonIps != null">
|
<div v-if="commonIps != null">
|
||||||
<i v-if="!commonIps[item.ip]?.length">
|
<i v-if="!commonIps[item.ip]?.length"> No other users share this IP. </i>
|
||||||
No other users share this IP.
|
<a-list v-else :data-source="!!commonIps ? commonIps[item.ip] : []">
|
||||||
</i>
|
|
||||||
<a-list
|
|
||||||
v-else
|
|
||||||
:data-source="!!commonIps ? commonIps[item.ip] : []"
|
|
||||||
>
|
|
||||||
<template #renderItem="{ item: otherItem }">
|
<template #renderItem="{ item: otherItem }">
|
||||||
<nuxt-link :to="`/user/${otherItem._id}`">
|
<nuxt-link :to="`/user/${otherItem._id}`">
|
||||||
{{ otherItem.username }}
|
{{ otherItem.username }}
|
||||||
@ -83,16 +68,10 @@
|
|||||||
<b>{{ user?.profile.isAdmin ? "an admin" : "a regular user" }}</b
|
<b>{{ user?.profile.isAdmin ? "an admin" : "a regular user" }}</b
|
||||||
>.
|
>.
|
||||||
</span>
|
</span>
|
||||||
<a-button
|
<a-button danger v-if="!user?.profile.isAdmin" @click="() => (showDemote = true)">
|
||||||
danger
|
|
||||||
v-if="!user?.profile.isAdmin"
|
|
||||||
@click="() => (showDemote = true)"
|
|
||||||
>
|
|
||||||
<b>Promote to Admin</b>
|
<b>Promote to Admin</b>
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button v-else @click="() => (showDemote = true)">
|
<a-button v-else @click="() => (showDemote = true)"> Demote to regular user </a-button>
|
||||||
Demote to regular user
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
</a-space>
|
||||||
<a-divider />
|
<a-divider />
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
@ -110,8 +89,7 @@
|
|||||||
v-model:open="showBanUnban"
|
v-model:open="showBanUnban"
|
||||||
:title="`${user?.banned ? 'Unban' : 'Ban'} ${user?.username}`"
|
:title="`${user?.banned ? 'Unban' : 'Ban'} ${user?.username}`"
|
||||||
>
|
>
|
||||||
Are you sure you want to {{ `${user?.banned ? "unban" : "ban"}` }}
|
Are you sure you want to {{ `${user?.banned ? "unban" : "ban"}` }} {{ user?.username }}?
|
||||||
{{ user?.username }}?
|
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<a-modal
|
<a-modal
|
||||||
cancel-text="No"
|
cancel-text="No"
|
||||||
@ -119,20 +97,13 @@
|
|||||||
@ok="prodem"
|
@ok="prodem"
|
||||||
@cancel="() => (showDemote = false)"
|
@cancel="() => (showDemote = false)"
|
||||||
v-model:open="showDemote"
|
v-model:open="showDemote"
|
||||||
:title="`${short ? 'Demoting' : 'Promoting'} ${user?.username} ${
|
:title="`${short ? 'Demoting' : 'Promoting'} ${user?.username} ${!short ? 'to an administrator' : 'to a regular user'}`"
|
||||||
!short ? 'to an administrator' : 'to a regular user'
|
|
||||||
}`"
|
|
||||||
>
|
>
|
||||||
<div v-if="!short">
|
<div v-if="!short">
|
||||||
Are you <b><u>absolutely sure</u></b> you want to
|
Are you <b><u>absolutely sure</u></b> you want to <b>promote this user to an admin</b>?
|
||||||
<b>promote this user to an admin</b>?
|
|
||||||
<br />
|
<br />
|
||||||
<a-typography-title :level="5">
|
<a-typography-title :level="5"> This is a VERY dangerous permission to grant. </a-typography-title>
|
||||||
This is a VERY dangerous permission to grant.
|
|
||||||
</a-typography-title>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
Are you sure you want to remove this user as an administrator?
|
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else>Are you sure you want to remove this user as an administrator?</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
import { SingleChapterResult } from "@client/types/slightlyDifferentStory";
|
import { SingleChapterResult } from "@client/types/slightlyDifferentStory";
|
||||||
const props = defineProps<{ endpoint: string }>();
|
const props = defineProps<{ endpoint: string }>();
|
||||||
const story = inject<SingleChapterResult>("story");
|
const story = inject<SingleChapterResult>("story");
|
||||||
const { data: reviews } = (await useApiFetch<IReview[]>(
|
const { data: reviews } = (await useApiFetch<IReview[]>(`${props.endpoint}/reviews`)) as unknown as {
|
||||||
`${props.endpoint}/reviews`,
|
|
||||||
)) as unknown as {
|
|
||||||
data: IReview[];
|
data: IReview[];
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,20 +12,12 @@
|
|||||||
});
|
});
|
||||||
return unflattened.flat(Infinity).map((a) => ({ value: a, label: a }));
|
return unflattened.flat(Infinity).map((a) => ({ value: a, label: a }));
|
||||||
});
|
});
|
||||||
const charField = useField<string[]>(
|
const charField = useField<string[]>(fname + "characters", cs.fields.characters as unknown as MaybeRef<RuleExpression<string[]>>);
|
||||||
fname + "characters",
|
|
||||||
cs.fields.characters as unknown as MaybeRef<RuleExpression<string[]>>,
|
|
||||||
);
|
|
||||||
const { value, errorMessage, name: bandName, setValue } = charField;
|
const { value, errorMessage, name: bandName, setValue } = charField;
|
||||||
// setValue([]);
|
// setValue([]);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item :help="errorMessage" label="Characters" :name="bandName as string" :validate-status="!!errorMessage ? 'error' : undefined">
|
||||||
:help="errorMessage"
|
|
||||||
label="Characters"
|
|
||||||
:name="bandName as string"
|
|
||||||
:validate-status="!!errorMessage ? 'error' : undefined"
|
|
||||||
>
|
|
||||||
<a-select mode="multiple" :options="opts" v-model:value="value">
|
<a-select mode="multiple" :options="opts" v-model:value="value">
|
||||||
<template #removeIcon>
|
<template #removeIcon>
|
||||||
<i class="far fa-circle-x" />
|
<i class="far fa-circle-x" />
|
||||||
|
@ -6,22 +6,11 @@
|
|||||||
value: a,
|
value: a,
|
||||||
label: a,
|
label: a,
|
||||||
}));
|
}));
|
||||||
const { value, errorMessage, name, setValue } = useField<string[]>(
|
const { value, errorMessage, name, setValue } = useField<string[]>(fname + "genre");
|
||||||
fname + "genre",
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item :help="errorMessage" label="Genre(s)" :validate-status="!!errorMessage ? 'error' : undefined">
|
||||||
:help="errorMessage"
|
<a-select :allow-clear="true" :options="opts" v-model:value="value" mode="multiple">
|
||||||
label="Genre(s)"
|
|
||||||
:validate-status="!!errorMessage ? 'error' : undefined"
|
|
||||||
>
|
|
||||||
<a-select
|
|
||||||
:allow-clear="true"
|
|
||||||
:options="opts"
|
|
||||||
v-model:value="value"
|
|
||||||
mode="multiple"
|
|
||||||
>
|
|
||||||
<template #removeIcon>
|
<template #removeIcon>
|
||||||
<i class="far fa-circle-x" />
|
<i class="far fa-circle-x" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -12,26 +12,14 @@
|
|||||||
});
|
});
|
||||||
return uf.flat(Infinity).map((a) => ({ value: a, label: a }));
|
return uf.flat(Infinity).map((a) => ({ value: a, label: a }));
|
||||||
});
|
});
|
||||||
const { fields, push, remove, replace, update } = useFieldArray<string[]>(
|
const { fields, push, remove, replace, update } = useFieldArray<string[]>(fname + "relationships");
|
||||||
fname + "relationships",
|
|
||||||
);
|
|
||||||
// replace([]);
|
// replace([]);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-form-item label="Pairings">
|
<a-form-item label="Pairings">
|
||||||
<a-row
|
<a-row :gutter="5" :wrap="true" v-for="(field, idx) in fields" :key="field.key">
|
||||||
:gutter="5"
|
|
||||||
:wrap="true"
|
|
||||||
v-for="(field, idx) in fields"
|
|
||||||
:key="field.key"
|
|
||||||
>
|
|
||||||
<Field :name="fname + 'relationships' + `[${idx}]`">
|
<Field :name="fname + 'relationships' + `[${idx}]`">
|
||||||
<a-select
|
<a-select mode="multiple" :options="opts" v-model:value="field.value as string[]" @change="(val) => update(idx, val as string[])">
|
||||||
mode="multiple"
|
|
||||||
:options="opts"
|
|
||||||
v-model:value="field.value as string[]"
|
|
||||||
@change="(val) => update(idx, val as string[])"
|
|
||||||
>
|
|
||||||
<template #removeIcon>
|
<template #removeIcon>
|
||||||
<i class="far fa-circle-x" />
|
<i class="far fa-circle-x" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
mode="multiple"
|
mode="multiple"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="Please select"
|
placeholder="Please select"
|
||||||
:options="
|
:options="[...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) }))"
|
||||||
[...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) }))
|
|
||||||
"
|
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
></a-select>
|
></a-select>
|
||||||
</template>
|
</template>
|
||||||
|
@ -8,77 +8,45 @@
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-card style="width: 45%; float: left; margin-right: 1.2em" v-if="!!story">
|
<a-card style="width: 45%; float: left; margin-right: 1.2em" v-if="!!story">
|
||||||
<a-descriptions
|
<a-descriptions :label-style="{ fontWeight: 'bold' }" :colon="false" :column="1">
|
||||||
:label-style="{ fontWeight: 'bold' }"
|
|
||||||
:colon="false"
|
|
||||||
:column="1"
|
|
||||||
>
|
|
||||||
<a-descriptions-item label="Author">
|
<a-descriptions-item label="Author">
|
||||||
<nuxt-link :to="`/user/${story?.author._id}`">{{
|
<nuxt-link :to="`/user/${story?.author._id}`">{{ story?.author.username }}</nuxt-link>
|
||||||
story?.author.username
|
|
||||||
}}</nuxt-link>
|
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Bands">
|
<a-descriptions-item label="Bands">
|
||||||
<div
|
<div class="wrapLong" v-for="(item, index) in story?.currentChapter.bands">
|
||||||
class="wrapLong"
|
|
||||||
v-for="(item, index) in story?.currentChapter.bands"
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<nuxt-link :to="`/band/${item._id}`">
|
<nuxt-link :to="`/band/${item._id}`">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
{{
|
{{ (index < story!.currentChapter?.bands.length - 1 && ", ") || "" }}
|
||||||
(index < story!.currentChapter?.bands.length - 1 && ", ") ||
|
|
||||||
""
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Genre(s)">
|
<a-descriptions-item label="Genre(s)">
|
||||||
<div
|
<div class="wrapLong" v-for="(item, index) in story?.currentChapter.genre">
|
||||||
class="wrapLong"
|
|
||||||
v-for="(item, index) in story?.currentChapter.genre"
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
{{ item }}
|
{{ item }}
|
||||||
{{
|
{{ (index < story!.currentChapter?.genre.length - 1 && ", ") || "" }}
|
||||||
(index < story!.currentChapter?.genre.length - 1 && ", ") ||
|
|
||||||
""
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Relationship(s)">
|
<a-descriptions-item label="Relationship(s)">
|
||||||
<div
|
<div class="wrapLong" v-for="(item, index) in story?.currentChapter.relationships">
|
||||||
class="wrapLong"
|
|
||||||
v-for="(item, index) in story?.currentChapter.relationships"
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
{{ item.join("/") }}
|
{{ item.join("/") }}
|
||||||
{{
|
{{ (index < story!.currentChapter?.relationships.length - 1 && ", ") || "" }}
|
||||||
(index < story!.currentChapter?.relationships.length - 1 &&
|
|
||||||
", ") ||
|
|
||||||
""
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Character(s)">
|
<a-descriptions-item label="Character(s)">
|
||||||
<div class="wrapLong">
|
<div class="wrapLong">
|
||||||
<span v-for="(item, index) in story?.currentChapter.characters">
|
<span v-for="(item, index) in story?.currentChapter.characters">
|
||||||
{{ item
|
{{ item }}{{ (index < story!.currentChapter?.characters.length - 1 && ", ") || "" }}
|
||||||
}}{{
|
|
||||||
(index < story!.currentChapter?.characters.length - 1 &&
|
|
||||||
", ") ||
|
|
||||||
""
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Rating">
|
<a-descriptions-item label="Rating">
|
||||||
{{
|
{{ story?.currentChapter.nsfw ? "Adult" : "Suitable for most audiences" }}
|
||||||
story?.currentChapter.nsfw ? "Adult" : "Suitable for most audiences"
|
|
||||||
}}
|
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="Summary">
|
<a-descriptions-item label="Summary">
|
||||||
<div v-html="story?.currentChapter.summary"></div>
|
<div v-html="story?.currentChapter.summary"></div>
|
||||||
@ -86,19 +54,9 @@
|
|||||||
<a-descriptions-item label="Date posted">
|
<a-descriptions-item label="Date posted">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>
|
<template #title>
|
||||||
{{
|
{{ format(Date.parse(story?.currentChapter.posted as unknown as string), "EEEE, LLL dd yyyy @ hh:mm:ss.SSS aa") }}
|
||||||
format(
|
|
||||||
Date.parse(story?.currentChapter.posted as unknown as string),
|
|
||||||
"EEEE, LLL dd yyyy @ hh:mm:ss.SSS aa",
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</template>
|
</template>
|
||||||
{{
|
{{ format(Date.parse(story?.currentChapter.posted as unknown as string), "yyyy-MM-dd") }}
|
||||||
format(
|
|
||||||
Date.parse(story?.currentChapter.posted as unknown as string),
|
|
||||||
"yyyy-MM-dd",
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
@ -106,12 +64,7 @@
|
|||||||
<div class="stats">
|
<div class="stats">
|
||||||
<span>
|
<span>
|
||||||
<span class="staticon">
|
<span class="staticon">
|
||||||
<icon
|
<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#ff2883" :size="12" name="heart" />
|
||||||
:istyle="!dark ? 'solid' : 'regular'"
|
|
||||||
icolor="#ff2883"
|
|
||||||
:size="12"
|
|
||||||
name="heart"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{{ story.favs }}
|
{{ story.favs }}
|
||||||
@ -119,12 +72,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<span class="staticon">
|
<span class="staticon">
|
||||||
<icon
|
<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#1787d7" :size="12" name="book-open" />
|
||||||
:istyle="!dark ? 'solid' : 'regular'"
|
|
||||||
icolor="#1787d7"
|
|
||||||
:size="12"
|
|
||||||
name="book-open"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{{ story.views }}
|
{{ story.views }}
|
||||||
@ -132,12 +80,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<span class="staticon">
|
<span class="staticon">
|
||||||
<icon
|
<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#51e07c" :size="12" name="thumbs-up" />
|
||||||
:istyle="!dark ? 'solid' : 'regular'"
|
|
||||||
icolor="#51e07c"
|
|
||||||
:size="12"
|
|
||||||
name="thumbs-up"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{{ story.recs }}
|
{{ story.recs }}
|
||||||
@ -145,12 +88,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<span class="staticon">
|
<span class="staticon">
|
||||||
<icon
|
<icon :istyle="!dark ? 'solid' : 'regular'" icolor="#c2d420" :size="12" name="download" />
|
||||||
:istyle="!dark ? 'solid' : 'regular'"
|
|
||||||
icolor="#c2d420"
|
|
||||||
:size="12"
|
|
||||||
name="download"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{{ story.downloads }}
|
{{ story.downloads }}
|
||||||
|
@ -2,95 +2,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h3>Age Policy</h3>
|
<h3>Age Policy</h3>
|
||||||
You must be 18 years of age or older to have an account. If you are found to
|
You must be 18 years of age or older to have an account. If you are found to be underage, your account will be suspended without notice.
|
||||||
be underage, your account will be suspended without notice.
|
|
||||||
<h3>General</h3>
|
<h3>General</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li>Rockfic.com is not affiliated with any band listed on the site;</li>
|
<li>Rockfic.com is not affiliated with any band listed on the site;</li>
|
||||||
<li>
|
<li>
|
||||||
All stories are fictional and for entertainment purposes only, which
|
All stories are fictional and for entertainment purposes only, which means that while the characters may be loosely based on the public personas of real
|
||||||
means that while the characters may be loosely based on the public
|
people, the stories are completely ungrounded from reality and are in no way meant to reflect the private lives, actual practices, or activities of any
|
||||||
personas of real people, the stories are completely ungrounded from
|
persons named;
|
||||||
reality and are in no way meant to reflect the private lives, actual
|
|
||||||
practices, or activities of any persons named;
|
|
||||||
</li>
|
</li>
|
||||||
|
<li>Rockfic.com will remove a work of fiction if an individual named within requests its removal;</li>
|
||||||
|
<li>We do not sell, trade or otherwise disclose personal user information to any third party;</li>
|
||||||
<li>
|
<li>
|
||||||
Rockfic.com will remove a work of fiction if an individual named within
|
We reserve the right to access and disclose individually identifiable information to comply with any legal obligation or governmental request to enforce
|
||||||
requests its removal;
|
or apply our Terms of Use, or to ensure the constitutional rights and safety of Rockfic.com users.
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
We do not sell, trade or otherwise disclose personal user information to
|
|
||||||
any third party;
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
We reserve the right to access and disclose individually identifiable
|
|
||||||
information to comply with any legal obligation or governmental request
|
|
||||||
to enforce or apply our Terms of Use, or to ensure the constitutional
|
|
||||||
rights and safety of Rockfic.com users.
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h3>Content</h3>
|
<h3>Content</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>Rockfic.com does not own any of the stories published on the site, nor are its administrators legally accountable for its content;</li>
|
||||||
Rockfic.com does not own any of the stories published on the site, nor
|
|
||||||
are its administrators legally accountable for its content;
|
|
||||||
</li>
|
|
||||||
<li>Authors are the sole copyright owners of their stories;</li>
|
<li>Authors are the sole copyright owners of their stories;</li>
|
||||||
|
<li>Authors are responsible for managing any content they create; this includes managing the privacy settings facilitated by the site;</li>
|
||||||
<li>
|
<li>
|
||||||
Authors are responsible for managing any content they create; this
|
Rockfic.com reserves the right to remove content, including anything we consider offensive, inappropriate or defamatory, at our discretion; any content
|
||||||
includes managing the privacy settings facilitated by the site;
|
we decide to remove will be done in accordance with our Submission Rules;
|
||||||
|
</li>
|
||||||
|
<li>Rockfic.com reserves the right to edit content, in line with our Submission Rules.</li>
|
||||||
|
<li>
|
||||||
|
If you believe that you own the copyright in any of the content on Rockfic.com, and you have not been recognized as the copyright owner, please contact
|
||||||
|
us and your case will be investigated;
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Rockfic.com reserves the right to remove content, including anything we
|
While we investigate reports of inappropriate content or copyright issues, we may temporarily remove the content in question; if we agree that you are
|
||||||
consider offensive, inappropriate or defamatory, at our discretion; any
|
the copyright owner or that the content is inappropriate, we will remove the relevant content permanently.
|
||||||
content we decide to remove will be done in accordance with our
|
|
||||||
Submission Rules;
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Rockfic.com reserves the right to edit content, in line with our
|
|
||||||
Submission Rules.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
If you believe that you own the copyright in any of the content on
|
|
||||||
Rockfic.com, and you have not been recognized as the copyright owner,
|
|
||||||
please contact us and your case will be investigated;
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
While we investigate reports of inappropriate content or copyright
|
|
||||||
issues, we may temporarily remove the content in question; if we agree
|
|
||||||
that you are the copyright owner or that the content is inappropriate,
|
|
||||||
we will remove the relevant content permanently.
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h3>Conduct</h3>
|
<h3>Conduct</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>Rockfic.com operates a strict anti-bullying and anti-harassment policy; if you have an issue to report, contact us;</li>
|
||||||
Rockfic.com operates a strict anti-bullying and anti-harassment policy;
|
|
||||||
if you have an issue to report, contact us;
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
Rockfic.com will permanently ban users who:
|
Rockfic.com will permanently ban users who:
|
||||||
<ol style="list-style-type: lower-alpha">
|
<ol style="list-style-type: lower-alpha">
|
||||||
<li>
|
<li>break the law, for example by saying something libellous, or by posting something which results in a criminal offence;</li>
|
||||||
break the law, for example by saying something libellous, or by
|
|
||||||
posting something which results in a criminal offence;
|
|
||||||
</li>
|
|
||||||
<li>share the personal details of users without their permission;</li>
|
<li>share the personal details of users without their permission;</li>
|
||||||
<li>impersonate another user;</li>
|
<li>impersonate another user;</li>
|
||||||
<li>
|
<li>collect or use any information from Rockfic.com with the intent to harm, discredit or harass any other user; or</li>
|
||||||
collect or use any information from Rockfic.com with the intent to
|
|
||||||
harm, discredit or harass any other user; or
|
|
||||||
</li>
|
|
||||||
<li>do anything which impacts the performance of the site.</li>
|
<li>do anything which impacts the performance of the site.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h3>Copyright</h3>
|
<h3>Copyright</h3>
|
||||||
All content on this site is copyright of its respective author. You may not,
|
All content on this site is copyright of its respective author. You may not, except with our express written permission, distribute or commercially exploit
|
||||||
except with our express written permission, distribute or commercially
|
the content. Nor may you transmit it or store it in any other website or other form of electronic retrieval system.
|
||||||
exploit the content. Nor may you transmit it or store it in any other
|
|
||||||
website or other form of electronic retrieval system.
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -60,8 +60,7 @@ export const fancy = {
|
|||||||
items: "h1 h2 h3 h4 h5 h6",
|
items: "h1 h2 h3 h4 h5 h6",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
toolbar:
|
toolbar: "undo redo | paste | bold italic underline | hr image link | forecolor styles | heading alignment | code",
|
||||||
"undo redo | paste | bold italic underline | hr image link | forecolor styles | heading alignment | code",
|
|
||||||
contextmenu: "bold italic underline | hr | link | image | paste",
|
contextmenu: "bold italic underline | hr | link | image | paste",
|
||||||
external_plugins: {
|
external_plugins: {
|
||||||
mentions: "/plugins/mentions/plugin.min.js",
|
mentions: "/plugins/mentions/plugin.min.js",
|
||||||
@ -122,11 +121,7 @@ export const story = {
|
|||||||
`advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table advcode help wordcount save`.split(
|
`advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table advcode help wordcount save`.split(
|
||||||
" ",
|
" ",
|
||||||
),
|
),
|
||||||
toolbar:
|
toolbar: "undo redo | paste |" + "bold italic underline | hr | alignleft aligncenter " + "alignright alignjustify | " + "| code",
|
||||||
"undo redo | paste |" +
|
|
||||||
"bold italic underline | hr | alignleft aligncenter " +
|
|
||||||
"alignright alignjustify | " +
|
|
||||||
"| code",
|
|
||||||
contextmenu: "bold italic underline | hr | paste | link",
|
contextmenu: "bold italic underline | hr | paste | link",
|
||||||
};
|
};
|
||||||
export const bare = {
|
export const bare = {
|
||||||
|
@ -3,12 +3,7 @@ import { FavPayload, HidePayload, SubPayload } from "./types/form/favSub";
|
|||||||
|
|
||||||
const base = `/user/me`;
|
const base = `/user/me`;
|
||||||
|
|
||||||
export const favourites = (
|
export const favourites = (values: (any & { _id: number })[], id: number, remove: boolean, type: "story" | "author") => {
|
||||||
values: (any & { _id: number })[],
|
|
||||||
id: number,
|
|
||||||
remove: boolean,
|
|
||||||
type: "story" | "author",
|
|
||||||
) => {
|
|
||||||
values?.splice(
|
values?.splice(
|
||||||
values!.findIndex((a) => a._id == id),
|
values!.findIndex((a) => a._id == id),
|
||||||
1,
|
1,
|
||||||
@ -26,12 +21,7 @@ export const favourites = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const subscriptions = (
|
export const subscriptions = (values: (any & { _id: number })[], id: number, action: "hide" | "subscribe" | "unsubscribe", type: "bands" | "authors") => {
|
||||||
values: (any & { _id: number })[],
|
|
||||||
id: number,
|
|
||||||
action: "hide" | "subscribe" | "unsubscribe",
|
|
||||||
type: "bands" | "authors",
|
|
||||||
) => {
|
|
||||||
values?.splice(
|
values?.splice(
|
||||||
values!.findIndex((a) => a._id == id),
|
values!.findIndex((a) => a._id == id),
|
||||||
1,
|
1,
|
||||||
|
@ -3,15 +3,16 @@ import { IChapter } from "@models/stories/chapter";
|
|||||||
import { IStory } from "@models/stories";
|
import { IStory } from "@models/stories";
|
||||||
import { messages } from "@server/constants";
|
import { messages } from "@server/constants";
|
||||||
import { IUser } from "@models/user";
|
import { IUser } from "@models/user";
|
||||||
|
import { IDraft } from "@models/stories/draft";
|
||||||
|
|
||||||
|
const show404 = () => showError({ statusCode: 404, message: messages[404] });
|
||||||
|
|
||||||
export const storyMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
|
export const storyMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
const { getSession } = useAuth();
|
const { getSession } = useAuth();
|
||||||
await getSession({ force: true });
|
await getSession({ force: true });
|
||||||
const { data } = useAuth();
|
const { data } = useAuth();
|
||||||
console.log("to n from", to, from, data);
|
console.log("to n from", to, from, data);
|
||||||
const { data: story, error } = await useApiFetch<SingleChapterResult>(
|
const { data: story, error } = await useApiFetch<SingleChapterResult>(to.path);
|
||||||
to.path,
|
|
||||||
);
|
|
||||||
if (error.value) {
|
if (error.value) {
|
||||||
return showError(error.value);
|
return showError(error.value);
|
||||||
} else if (!story.value) {
|
} else if (!story.value) {
|
||||||
@ -23,24 +24,27 @@ export const storyMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const storyEditMiddleware = defineNuxtRouteMiddleware(
|
export const storyEditMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
async (to, from) => {
|
const { data: curU } = useAuth();
|
||||||
const { data: curU } = useAuth();
|
const rtr = useRoute();
|
||||||
const rtr = useRoute();
|
const { data: storyInfo } = await useApiFetch<({ chapters: (IChapter & { text: string })[] } & IStory) | null>(`/story/${rtr.params.id}/full`);
|
||||||
const { data: storyInfo } = await useApiFetch<
|
if (!storyInfo.value) show404();
|
||||||
({ chapters: (IChapter & { text: string })[] } & IStory) | null
|
if (curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id && curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id) {
|
||||||
>(`/story/${rtr.params.id}/full`);
|
return showError({
|
||||||
if (!storyInfo.value) {
|
statusCode: 403,
|
||||||
return showError({ statusCode: 404, message: messages[404] });
|
message: messages[403],
|
||||||
}
|
});
|
||||||
if (
|
}
|
||||||
curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id &&
|
});
|
||||||
curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id
|
export const draftEditMiddleware = defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
) {
|
const { data: curU } = useAuth();
|
||||||
return showError({
|
const rtr = useRoute();
|
||||||
statusCode: 403,
|
const { data: storyInfo } = await useApiFetch<IDraft | null>(`/draft/${rtr.params.id}`);
|
||||||
message: messages[403],
|
if (!storyInfo.value) show404();
|
||||||
});
|
if (curU.value?.user?._id !== (storyInfo.value?.author as IUser)._id && curU.value?.user?._id !== (storyInfo.value?.coAuthor as IUser)?._id) {
|
||||||
}
|
return showError({
|
||||||
},
|
statusCode: 403,
|
||||||
);
|
message: messages[403],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
3
lib/client/types/form/draftInfo.ts
Normal file
3
lib/client/types/form/draftInfo.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface DraftInfo {
|
||||||
|
id: number;
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
import { V4Options, v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
|
import { IChapter } from "@models/stories/chapter";
|
||||||
|
import { IBand } from "@models/band";
|
||||||
|
|
||||||
export interface FormChapter {
|
export interface FormChapter {
|
||||||
id?: number;
|
id?: number;
|
||||||
@ -51,3 +53,21 @@ export const defaultStory: FormStory = {
|
|||||||
challenge: null,
|
challenge: null,
|
||||||
completed: false,
|
completed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function toFormChapter(chap: IChapter & { text: string }): FormChapter {
|
||||||
|
return {
|
||||||
|
chapterTitle: chap.title,
|
||||||
|
index: 1,
|
||||||
|
summary: chap.summary,
|
||||||
|
notes: chap.notes,
|
||||||
|
genre: chap.genre,
|
||||||
|
bands: (chap.bands as IBand[]).map((a) => a._id),
|
||||||
|
characters: chap.characters,
|
||||||
|
relationships: chap.relationships,
|
||||||
|
nsfw: chap.nsfw,
|
||||||
|
loggedInOnly: chap.loggedInOnly,
|
||||||
|
hidden: chap.hidden,
|
||||||
|
content: chap.text,
|
||||||
|
uuidKey: v4(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -27,11 +27,7 @@ export const autoSave = async (values: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const autoEdit = (
|
export const autoEdit = (values: any, endpoint: string, method: "put" | "post") => {
|
||||||
values: any,
|
|
||||||
endpoint: string,
|
|
||||||
method: "put" | "post",
|
|
||||||
) => {
|
|
||||||
const [messageApi, contextHolder] = message.useMessage();
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
useApiFetch<{ success: boolean; data: IStory }>(endpoint, {
|
useApiFetch<{ success: boolean; data: IStory }>(endpoint, {
|
||||||
method,
|
method,
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import turndown from "turndown";
|
import turndown from "turndown";
|
||||||
export const ContentFilenameRegex = /\.(doc|docx|md|markdown)$/i;
|
export const ContentFilenameRegex = /\.(doc|docx|md|markdown)$/i;
|
||||||
|
|
||||||
export const emailRegex: RegExp =
|
export const emailRegex: RegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
|
||||||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
|
export const usernameRegex: (uname: string) => RegExp = (uname: string) => new RegExp("^" + uname.trim().replace(/\*/g, "\\*") + "$", "i");
|
||||||
export const usernameRegex: (uname: string) => RegExp = (uname: string) =>
|
|
||||||
new RegExp("^" + uname.trim().replace(/\*/g, "\\*") + "$", "i");
|
|
||||||
export const mammothTemplate = (doc, defaults, content) => {
|
export const mammothTemplate = (doc, defaults, content) => {
|
||||||
return content.replace(/\n|\r\n|\r/gm, "");
|
return content.replace(/\n|\r\n|\r/gm, "");
|
||||||
};
|
};
|
||||||
@ -90,17 +88,7 @@ export const sanitizeConf = {
|
|||||||
img: ["src"],
|
img: ["src"],
|
||||||
},
|
},
|
||||||
// Lots of these won't come up by default because we don't allow them
|
// Lots of these won't come up by default because we don't allow them
|
||||||
selfClosing: [
|
selfClosing: ["img", "br", "hr", "area", "base", "basefont", "input", "link", "meta"],
|
||||||
"img",
|
|
||||||
"br",
|
|
||||||
"hr",
|
|
||||||
"area",
|
|
||||||
"base",
|
|
||||||
"basefont",
|
|
||||||
"input",
|
|
||||||
"link",
|
|
||||||
"meta",
|
|
||||||
],
|
|
||||||
// URL schemes we permit
|
// URL schemes we permit
|
||||||
allowedSchemes: ["http", "https", "ftp", "mailto", "tel"],
|
allowedSchemes: ["http", "https", "ftp", "mailto", "tel"],
|
||||||
allowedSchemesAppliedToAttributes: ["href", "src", "cite"],
|
allowedSchemesAppliedToAttributes: ["href", "src", "cite"],
|
||||||
|
20
lib/server/dbHelpers/draftHydrator.ts
Normal file
20
lib/server/dbHelpers/draftHydrator.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Document } from "mongoose";
|
||||||
|
import { IDraft } from "@models/stories/draft";
|
||||||
|
import { EventHandlerRequest, H3Event } from "h3";
|
||||||
|
import { IChapter } from "@models/stories/chapter";
|
||||||
|
import getDraftBucket from "@server/storyHelpers/getDraftBucket";
|
||||||
|
import { norm, stringifyStream } from "@functions";
|
||||||
|
|
||||||
|
export interface HydratedDraft extends Omit<IDraft, "chapters"> {
|
||||||
|
chapters: (IChapter & { text: string })[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function (draft: Document<number, {}, IDraft> & IDraft, event: H3Event<EventHandlerRequest>): Promise<HydratedDraft> {
|
||||||
|
const finObj = draft.toObject() as HydratedDraft;
|
||||||
|
const bucket = getDraftBucket();
|
||||||
|
for (let chap of finObj.chapters) {
|
||||||
|
let dstream = bucket.openDownloadStreamByName(`/drafts/${chap.id}.txt`);
|
||||||
|
chap.text = norm(await stringifyStream(dstream));
|
||||||
|
}
|
||||||
|
return finObj;
|
||||||
|
}
|
@ -20,7 +20,6 @@ export default async function (ev: H3Event<EventHandlerRequest>) {
|
|||||||
})
|
})
|
||||||
.populate({ path: "challenge", model: Challenge })
|
.populate({ path: "challenge", model: Challenge })
|
||||||
.exec();
|
.exec();
|
||||||
if (story == null)
|
if (story == null) throw createError({ statusCode: 404, message: "Not found." });
|
||||||
throw createError({ statusCode: 404, message: "Not found." });
|
|
||||||
return story;
|
return story;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
export const submissionsOpen = () =>
|
export const submissionsOpen = () =>
|
||||||
new Date() < new Date(Date.parse(`Dec 24 ${new Date().getFullYear()}`)) &&
|
new Date() < new Date(Date.parse(`Dec 24 ${new Date().getFullYear()}`)) && Date.now() > Date.parse(`Nov 1 ${new Date().getFullYear()}`);
|
||||||
Date.now() > Date.parse(`Nov 1 ${new Date().getFullYear()}`);
|
export const ficsHidden = (d: number) => d < Date.parse(`Dec 25 ${new Date().getFullYear()}`);
|
||||||
export const ficsHidden = (d: number) =>
|
export const status = () => Date.now() > Date.parse(`Oct 1 ${new Date().getFullYear()}`) && Date.now() < Date.parse(`Nov 30 ${new Date().getFullYear()}`);
|
||||||
d < Date.parse(`Dec 25 ${new Date().getFullYear()}`);
|
|
||||||
export const status = () =>
|
|
||||||
Date.now() > Date.parse(`Oct 1 ${new Date().getFullYear()}`) &&
|
|
||||||
Date.now() < Date.parse(`Nov 30 ${new Date().getFullYear()}`);
|
|
||||||
|
@ -5,25 +5,13 @@ import { IDraft } from "@models/stories/draft";
|
|||||||
import { IUser } from "@models/user";
|
import { IUser } from "@models/user";
|
||||||
export function canDelete(event: H3Event<EventHandlerRequest>, story: IStory) {
|
export function canDelete(event: H3Event<EventHandlerRequest>, story: IStory) {
|
||||||
isLoggedIn(event);
|
isLoggedIn(event);
|
||||||
return (
|
return event.context.currentUser?.profile.isAdmin || (story.author as IUser)._id === event.context.currentUser?._id;
|
||||||
event.context.currentUser?.profile.isAdmin ||
|
|
||||||
(story.author as IUser)._id === event.context.currentUser?._id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
export function canDeleteDraft(
|
export function canDeleteDraft(event: H3Event<EventHandlerRequest>, story: IDraft) {
|
||||||
event: H3Event<EventHandlerRequest>,
|
|
||||||
story: IDraft,
|
|
||||||
) {
|
|
||||||
isLoggedIn(event);
|
isLoggedIn(event);
|
||||||
return story.author === event.context.currentUser?._id;
|
return story.author === event.context.currentUser?._id;
|
||||||
}
|
}
|
||||||
export function canModify(
|
export function canModify(event: H3Event<EventHandlerRequest>, story: IStory | IDraft) {
|
||||||
event: H3Event<EventHandlerRequest>,
|
|
||||||
story: IStory | IDraft,
|
|
||||||
) {
|
|
||||||
isLoggedIn(event);
|
isLoggedIn(event);
|
||||||
return (
|
return event.context.currentUser?._id === (story.author as IUser)._id || (story.coAuthor as IUser)?._id === event.context.currentUser?._id;
|
||||||
event.context.currentUser?._id === (story.author as IUser)._id ||
|
|
||||||
(story.coAuthor as IUser)?._id === event.context.currentUser?._id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,9 @@ export default async function (bodyObj: FormChapter): Promise<string> {
|
|||||||
str = bodyObj.content;
|
str = bodyObj.content;
|
||||||
} else if (bodyObj.file) {
|
} else if (bodyObj.file) {
|
||||||
let ext = extname(bodyObj.file).toLowerCase();
|
let ext = extname(bodyObj.file).toLowerCase();
|
||||||
if (ext === ".md" || ext === ".markdown")
|
if (ext === ".md" || ext === ".markdown") str = marked.parse(readFileSync(resolve(`tmp/${bodyObj.file}`)).toString());
|
||||||
str = marked.parse(
|
|
||||||
readFileSync(resolve(`tmp/${bodyObj.file}`)).toString(),
|
|
||||||
);
|
|
||||||
else if (ext === ".doc" || ext === ".docx")
|
else if (ext === ".doc" || ext === ".docx")
|
||||||
str = (
|
str = (await mammoth.convertToHtml({ path: resolve(`tmp/${bodyObj.file}`) }, { styleMap: ["b => b", "i => i", "u => u"] })).value;
|
||||||
await mammoth.convertToHtml(
|
|
||||||
{ path: resolve(`tmp/${bodyObj.file}`) },
|
|
||||||
{ styleMap: ["b => b", "i => i", "u => u"] },
|
|
||||||
)
|
|
||||||
).value;
|
|
||||||
else
|
else
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import getBucket from "./getBucket";
|
import getBucket from "./getBucket";
|
||||||
import { Readable } from "stream";
|
import { Readable } from "stream";
|
||||||
export default async function replaceGridFS(
|
export default async function replaceGridFS(chapterID: number | undefined, content: string) {
|
||||||
chapterID: number | undefined,
|
|
||||||
content: string,
|
|
||||||
) {
|
|
||||||
let filename = `/stories/${chapterID}.txt`;
|
let filename = `/stories/${chapterID}.txt`;
|
||||||
const bucket = getBucket();
|
const bucket = getBucket();
|
||||||
if (chapterID) {
|
if (chapterID) {
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
import { subscriptions, bp } from "@client/listActions";
|
import { subscriptions, bp } from "@client/listActions";
|
||||||
import { IUser } from "@models/user";
|
import { IUser } from "@models/user";
|
||||||
|
|
||||||
const { data: bands } = (await useApiFetch<NonNullable<IBand[]>>(
|
const { data: bands } = (await useApiFetch<NonNullable<IBand[]>>("/band/all")) as unknown as { data: Ref<IBand[]> };
|
||||||
"/band/all",
|
|
||||||
)) as unknown as { data: Ref<IBand[]> };
|
|
||||||
|
|
||||||
const { data: rd }: { data: any } = useAuth();
|
const { data: rd }: { data: any } = useAuth();
|
||||||
const data = rd as { user: IUser };
|
const data = rd as { user: IUser };
|
||||||
@ -29,16 +27,10 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<!-- subscribe... -->
|
<!-- subscribe... -->
|
||||||
<a-col v-if="data && data.user?._id" style="margin-left: auto">
|
<a-col v-if="data && data.user?._id" style="margin-left: auto">
|
||||||
<a
|
<a v-if="!data?.user.subscriptions.bands.includes(item._id)" @click="(e) => hider(bands, item._id, 'subscribe', 'bands')">
|
||||||
v-if="!data?.user.subscriptions.bands.includes(item._id)"
|
|
||||||
@click="(e) => hider(bands, item._id, 'subscribe', 'bands')"
|
|
||||||
>
|
|
||||||
<icon :istyle="'regular'" name="paper-plane" :size="12" />
|
<icon :istyle="'regular'" name="paper-plane" :size="12" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a v-else @click="(e) => hider(bands, item._id, 'unsubscribe', 'bands')">
|
||||||
v-else
|
|
||||||
@click="(e) => hider(bands, item._id, 'unsubscribe', 'bands')"
|
|
||||||
>
|
|
||||||
<icon :istyle="'regular'" name="x" :size="12" />
|
<icon :istyle="'regular'" name="x" :size="12" />
|
||||||
</a>
|
</a>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 100%; height: 90vh">
|
<div style="width: 100%; height: 90vh">
|
||||||
<iframe
|
<iframe style="width: 100%; height: 100%" src="https://www.rockfic.com/forum/" />
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
src="https://www.rockfic.com/forum/"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -10,10 +10,5 @@
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-typography-title> Post a new Story </a-typography-title>
|
<a-typography-title> Post a new Story </a-typography-title>
|
||||||
<story-form
|
<story-form endpoint-method="post" :can-draft="true" :data="defaultStory" endpoint="/story/new" />
|
||||||
endpoint-method="post"
|
|
||||||
:can-draft="true"
|
|
||||||
:data="defaultStory"
|
|
||||||
endpoint="/story/new"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
middleware: [storyMiddleware],
|
middleware: [storyMiddleware],
|
||||||
});
|
});
|
||||||
const rtr = useRoute();
|
const rtr = useRoute();
|
||||||
const { data: story, error } = await useApiFetch<SingleChapterResult>(
|
const { data: story, error } = await useApiFetch<SingleChapterResult>(`/story/${rtr.params.id}/${rtr.params.cidx}`);
|
||||||
`/story/${rtr.params.id}/${rtr.params.cidx}`,
|
|
||||||
);
|
|
||||||
provide<SingleChapterResult | null>("story", story.value);
|
provide<SingleChapterResult | null>("story", story.value);
|
||||||
console.log("storyyy", story.value?.currentChapter);
|
console.log("storyyy", story.value?.currentChapter);
|
||||||
console.log(rtr);
|
console.log(rtr);
|
||||||
@ -52,55 +50,24 @@
|
|||||||
<div v-html="story?.currentChapter.text"></div>
|
<div v-html="story?.currentChapter.text"></div>
|
||||||
<a-divider style="background-color: #fff" />
|
<a-divider style="background-color: #fff" />
|
||||||
<a-button-group size="large" v-if="story.totalChapters > 1">
|
<a-button-group size="large" v-if="story.totalChapters > 1">
|
||||||
<a-button
|
<a-button v-if="parseInt(rtr.params.cidx as string) > 1" @click="() => navigateTo(`/story/${rtr.params.id}/1`)"> First </a-button>
|
||||||
v-if="parseInt(rtr.params.cidx as string) > 1"
|
<a-button v-if="parseInt(rtr.params.cidx as string) > 1" @click="() => navigateTo(`/story/${rtr.params.id}/${parseInt(rtr.params.cidx as string) - 1}`)">
|
||||||
@click="() => navigateTo(`/story/${rtr.params.id}/1`)"
|
|
||||||
>
|
|
||||||
First
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
v-if="parseInt(rtr.params.cidx as string) > 1"
|
|
||||||
@click="
|
|
||||||
() =>
|
|
||||||
navigateTo(
|
|
||||||
`/story/${rtr.params.id}/${
|
|
||||||
parseInt(rtr.params.cidx as string) - 1
|
|
||||||
}`,
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Previous
|
Previous
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="
|
v-if="parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1"
|
||||||
parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1
|
@click="() => navigateTo(`/story/${rtr.params.id}/${parseInt(rtr.params.cidx as string) + 1}`)"
|
||||||
"
|
|
||||||
@click="
|
|
||||||
() =>
|
|
||||||
navigateTo(
|
|
||||||
`/story/${rtr.params.id}/${
|
|
||||||
parseInt(rtr.params.cidx as string) + 1
|
|
||||||
}`,
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
@click="
|
@click="() => navigateTo(`/story/${rtr.params.id}/${story.chapterNames.length}`)"
|
||||||
() =>
|
v-if="parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1"
|
||||||
navigateTo(`/story/${rtr.params.id}/${story.chapterNames.length}`)
|
|
||||||
"
|
|
||||||
v-if="
|
|
||||||
parseInt(rtr.params.cidx as string) < story.chapterNames.length - 1
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
Last
|
Last
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-button-group>
|
</a-button-group>
|
||||||
<a-typography-title style="text-align: center" :level="2">
|
<a-typography-title style="text-align: center" :level="2"> Reviews </a-typography-title>
|
||||||
Reviews
|
|
||||||
</a-typography-title>
|
|
||||||
<for-chapter :endpoint="`/story/${rtr.params.id}/${rtr.params.cidx}`" />
|
<for-chapter :endpoint="`/story/${rtr.params.id}/${rtr.params.cidx}`" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
middleware: [storyMiddleware],
|
middleware: [storyMiddleware],
|
||||||
});
|
});
|
||||||
const rtr = useRoute();
|
const rtr = useRoute();
|
||||||
const { data: story, error } = await useApiFetch<IStory>(
|
const { data: story, error } = await useApiFetch<IStory>(`/story/${rtr.params.id}`);
|
||||||
`/story/${rtr.params.id}`,
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -15,10 +15,7 @@ export default eventHandler(async (event) => {
|
|||||||
await captcha(event);
|
await captcha(event);
|
||||||
console.log("fields exist");
|
console.log("fields exist");
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
$or: [
|
$or: [{ username: usernameRegex(body.username) }, { email: (body.email as string).toLowerCase() }],
|
||||||
{ username: usernameRegex(body.username) },
|
|
||||||
{ email: (body.email as string).toLowerCase() },
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
console.log("after f0", user);
|
console.log("after f0", user);
|
||||||
if (user)
|
if (user)
|
||||||
@ -27,7 +24,7 @@ export default eventHandler(async (event) => {
|
|||||||
message: "A user with that username or email already exists.",
|
message: "A user with that username or email already exists.",
|
||||||
});
|
});
|
||||||
let nuser = new User({
|
let nuser = new User({
|
||||||
email: body.email.toLowerCase(),
|
email: body.email.toLowerCase().trim(),
|
||||||
username: w2nc(body.username.trim()),
|
username: w2nc(body.username.trim()),
|
||||||
password: User.generateHash(body.password),
|
password: User.generateHash(body.password),
|
||||||
auth: {
|
auth: {
|
||||||
|
@ -14,10 +14,7 @@ let authorSingleton: {
|
|||||||
const threshold = 60 * 60 * 1000;
|
const threshold = 60 * 60 * 1000;
|
||||||
export default cachedEventHandler(
|
export default cachedEventHandler(
|
||||||
async (ev) => {
|
async (ev) => {
|
||||||
if (
|
if (Date.now() - authorSingleton.lastRefreshed >= threshold || authorSingleton.data.length < 1)
|
||||||
Date.now() - authorSingleton.lastRefreshed >= threshold ||
|
|
||||||
authorSingleton.data.length < 1
|
|
||||||
)
|
|
||||||
authorSingleton.data = await User.aggregate([
|
authorSingleton.data = await User.aggregate([
|
||||||
{ $project: { username: true, _id: true } },
|
{ $project: { username: true, _id: true } },
|
||||||
{
|
{
|
||||||
@ -38,10 +35,8 @@ export default cachedEventHandler(
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
authorSingleton.data.sort((a, b) => {
|
authorSingleton.data.sort((a, b) => {
|
||||||
if (a.username.toLocaleUpperCase() > b.username.toLocaleUpperCase())
|
if (a.username.toLocaleUpperCase() > b.username.toLocaleUpperCase()) return 1;
|
||||||
return 1;
|
else if (a.username.toLocaleUpperCase() < b.username.toLocaleUpperCase()) return -1;
|
||||||
else if (a.username.toLocaleUpperCase() < b.username.toLocaleUpperCase())
|
|
||||||
return -1;
|
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
return authorSingleton.data;
|
return authorSingleton.data;
|
||||||
|
@ -19,10 +19,7 @@ export default eventHandler(async (ev) => {
|
|||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: "bad parameter",
|
message: "bad parameter",
|
||||||
});
|
});
|
||||||
if (
|
if (ev.context.currentUser!._id != s2v?.author && ev.context.currentUser!._id != c2d._id)
|
||||||
ev.context.currentUser!._id != s2v?.author &&
|
|
||||||
ev.context.currentUser!._id != c2d._id
|
|
||||||
)
|
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: messages[403],
|
message: messages[403],
|
||||||
|
@ -4,9 +4,7 @@ import { isIdNan } from "@server/middlewareButNotReally";
|
|||||||
|
|
||||||
export default eventHandler(async (ev) => {
|
export default eventHandler(async (ev) => {
|
||||||
const revid = isIdNan(ev);
|
const revid = isIdNan(ev);
|
||||||
const r = await Review.findById(revid)
|
const r = await Review.findById(revid).populate("author", "username _id").exec();
|
||||||
.populate("author", "username _id")
|
|
||||||
.exec();
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
|
@ -32,8 +32,6 @@ export default eventHandler(async (ev) => {
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: await Review.findById(revid)
|
data: await Review.findById(revid).populate("author", "username profile _id").exec(),
|
||||||
.populate("author", "username profile _id")
|
|
||||||
.exec(),
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -20,9 +20,7 @@ export default eventHandler(async (ev) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(replyingTo?.author as IUser).blocked.includes(
|
(replyingTo?.author as IUser).blocked.includes(ev.context.currentUser!._id) ||
|
||||||
ev.context.currentUser!._id,
|
|
||||||
) ||
|
|
||||||
ev.context.currentUser!.blocked.includes((replyingTo?.author as IUser)._id)
|
ev.context.currentUser!.blocked.includes((replyingTo?.author as IUser)._id)
|
||||||
) {
|
) {
|
||||||
throw createError({
|
throw createError({
|
||||||
@ -40,9 +38,7 @@ export default eventHandler(async (ev) => {
|
|||||||
datePosted: new Date(),
|
datePosted: new Date(),
|
||||||
});
|
});
|
||||||
const { _id } = await newReply.save();
|
const { _id } = await newReply.save();
|
||||||
const nrs = (await Review.findOne({ _id })
|
const nrs = (await Review.findOne({ _id }).populate("author", "username _id blocked").exec())!;
|
||||||
.populate("author", "username _id blocked")
|
|
||||||
.exec())!;
|
|
||||||
replyingTo.replies.push(nrs._id);
|
replyingTo.replies.push(nrs._id);
|
||||||
await replyingTo.save();
|
await replyingTo.save();
|
||||||
const story = await Story.findById(replyingTo.leftOn);
|
const story = await Story.findById(replyingTo.leftOn);
|
||||||
@ -52,9 +48,7 @@ export default eventHandler(async (ev) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
back: `/story/${replyingTo.leftOn}/${
|
back: `/story/${replyingTo.leftOn}/${story!.chapters.findIndex((x) => x.id === nrs.whichChapter) + 1}`,
|
||||||
story!.chapters.findIndex((x) => x.id === nrs.whichChapter) + 1
|
|
||||||
}`,
|
|
||||||
data: nrs.toObject(),
|
data: nrs.toObject(),
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
|
@ -8,11 +8,7 @@ export default eventHandler(async (ev) => {
|
|||||||
isLoggedIn(ev);
|
isLoggedIn(ev);
|
||||||
const s = await storyQuerier(ev);
|
const s = await storyQuerier(ev);
|
||||||
const hidden = s.chapters.some((a) => a.hidden);
|
const hidden = s.chapters.some((a) => a.hidden);
|
||||||
if (
|
if (hidden && ev.context.currentUser?._id !== (s.author as IUser)._id && !ev.context.currentUser?.profile.isAdmin) {
|
||||||
hidden &&
|
|
||||||
ev.context.currentUser?._id !== (s.author as IUser)._id &&
|
|
||||||
!ev.context.currentUser?.profile.isAdmin
|
|
||||||
) {
|
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: messages[403],
|
message: messages[403],
|
||||||
|
@ -20,10 +20,7 @@ export default cachedEventHandler(
|
|||||||
async (event) => {
|
async (event) => {
|
||||||
let aa = mongoose.connection.db.collection("z_index_totAuthors");
|
let aa = mongoose.connection.db.collection("z_index_totAuthors");
|
||||||
let totalStories = await Story.countDocuments({ "chapters.hidden": false });
|
let totalStories = await Story.countDocuments({ "chapters.hidden": false });
|
||||||
if (
|
if (!authorSingleton.data.length || Date.now() - authorSingleton.lastRefreshed >= threshold) {
|
||||||
!authorSingleton.data.length ||
|
|
||||||
Date.now() - authorSingleton.lastRefreshed >= threshold
|
|
||||||
) {
|
|
||||||
authorSingleton.data = await User.aggregate([
|
authorSingleton.data = await User.aggregate([
|
||||||
{ $project: { username: true, _id: true } },
|
{ $project: { username: true, _id: true } },
|
||||||
{
|
{
|
||||||
|
@ -16,9 +16,5 @@ export default eventHandler(async (ev) => {
|
|||||||
})
|
})
|
||||||
.populate("story")
|
.populate("story")
|
||||||
.exec();
|
.exec();
|
||||||
return ar
|
return ar.map((a) => a.toObject()).sort((a, b) => b.datePosted.getMilliseconds() - a.datePosted.getMilliseconds());
|
||||||
.map((a) => a.toObject())
|
|
||||||
.sort(
|
|
||||||
(a, b) => b.datePosted.getMilliseconds() - a.datePosted.getMilliseconds(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
export default eventHandler(async (ev) => {
|
export default eventHandler(async (ev) => {
|
||||||
if (ev.context.currentUser) {
|
if (ev.context.currentUser) {
|
||||||
let log = ev.context.currentUser.ipLog;
|
let log = ev.context.currentUser.ipLog;
|
||||||
if (
|
if (ev.context.clientAddress !== undefined && !/127\.0\.0\.1|localhost|::1/.test(ev.context.clientAddress)) {
|
||||||
ev.context.clientAddress !== undefined &&
|
|
||||||
!/127\.0\.0\.1|localhost|::1/.test(ev.context.clientAddress)
|
|
||||||
) {
|
|
||||||
let found = log.findIndex((a) => a.ip === ev.context.clientAddress);
|
let found = log.findIndex((a) => a.ip === ev.context.clientAddress);
|
||||||
if (found !== -1) {
|
if (found !== -1) {
|
||||||
ev.context.currentUser.ipLog[found].lastAccess = new Date();
|
ev.context.currentUser.ipLog[found].lastAccess = new Date();
|
||||||
|
@ -4,10 +4,7 @@ export default eventHandler(async (event) => {
|
|||||||
let y = new Date().getFullYear();
|
let y = new Date().getFullYear();
|
||||||
let fmfilt: any = {};
|
let fmfilt: any = {};
|
||||||
|
|
||||||
if (
|
if (!!process.env.JulyFicmas && new Date() < new Date(Date.parse("Aug 1 " + y))) {
|
||||||
!!process.env.JulyFicmas &&
|
|
||||||
new Date() < new Date(Date.parse("Aug 1 " + y))
|
|
||||||
) {
|
|
||||||
fmfilt.isAnniversary = true;
|
fmfilt.isAnniversary = true;
|
||||||
fmfilt.year = y;
|
fmfilt.year = y;
|
||||||
} else if (new Date() < new Date(Date.parse("Dec 25 " + y))) {
|
} else if (new Date() < new Date(Date.parse("Dec 25 " + y))) {
|
||||||
|
@ -5,9 +5,7 @@ export default eventHandler(async (ev) => {
|
|||||||
ev.node.res.on("close", () => {
|
ev.node.res.on("close", () => {
|
||||||
p.done({
|
p.done({
|
||||||
label: "http/request",
|
label: "http/request",
|
||||||
message: `{${
|
message: `{${ev.context.currentUser?.username || "guest"}} | ${ev.method.toLocaleUpperCase()} @ ${ev._path}`,
|
||||||
ev.context.currentUser?.username || "guest"
|
|
||||||
}} | ${ev.method.toLocaleUpperCase()} @ ${ev._path}`,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
29
typings/auth.d.ts
vendored
29
typings/auth.d.ts
vendored
@ -1,12 +1,5 @@
|
|||||||
import { IUser } from "@models/user";
|
import { IUser } from "@models/user";
|
||||||
import {
|
import { GetSessionFunc, SecondarySignInOptions, SessionLastRefreshedAt, SessionStatus, SignInFunc, SignOutFunc } from "@sidebase/nuxt-auth/dist/runtime/types";
|
||||||
GetSessionFunc,
|
|
||||||
SecondarySignInOptions,
|
|
||||||
SessionLastRefreshedAt,
|
|
||||||
SessionStatus,
|
|
||||||
SignInFunc,
|
|
||||||
SignOutFunc,
|
|
||||||
} from "@sidebase/nuxt-auth/dist/runtime/types";
|
|
||||||
import { ComputedRef, Ref } from "vue";
|
import { ComputedRef, Ref } from "vue";
|
||||||
|
|
||||||
declare module "#auth" {
|
declare module "#auth" {
|
||||||
@ -24,18 +17,10 @@ declare module "@sidebase/nuxt-auth/dist/runtime/types" {
|
|||||||
declare const signIn: SignInFunc<Credentials, any>;
|
declare const signIn: SignInFunc<Credentials, any>;
|
||||||
declare const signOut: SignOutFunc;
|
declare const signOut: SignOutFunc;
|
||||||
declare const getSession: GetSessionFunc<SessionData | null | void>;
|
declare const getSession: GetSessionFunc<SessionData | null | void>;
|
||||||
declare const signUp: (
|
declare const signUp: (credentials: Credentials, signInOptions?: SecondarySignInOptions) => Promise<any>;
|
||||||
credentials: Credentials,
|
|
||||||
signInOptions?: SecondarySignInOptions,
|
|
||||||
) => Promise<any>;
|
|
||||||
|
|
||||||
type WrappedSessionData<SessionData> = Ref<SessionData | null | undefined>;
|
type WrappedSessionData<SessionData> = Ref<SessionData | null | undefined>;
|
||||||
export interface CommonUseAuthReturn<
|
export interface CommonUseAuthReturn<SignIn, SignOut, GetSession, SessionData> {
|
||||||
SignIn,
|
|
||||||
SignOut,
|
|
||||||
GetSession,
|
|
||||||
SessionData,
|
|
||||||
> {
|
|
||||||
data: Readonly<WrappedSessionData<SessionData>>;
|
data: Readonly<WrappedSessionData<SessionData>>;
|
||||||
lastRefreshedAt: Readonly<Ref<SessionLastRefreshedAt>>;
|
lastRefreshedAt: Readonly<Ref<SessionLastRefreshedAt>>;
|
||||||
status: ComputedRef<SessionStatus>;
|
status: ComputedRef<SessionStatus>;
|
||||||
@ -43,13 +28,7 @@ declare module "@sidebase/nuxt-auth/dist/runtime/types" {
|
|||||||
signOut: SignOut;
|
signOut: SignOut;
|
||||||
getSession: GetSession;
|
getSession: GetSession;
|
||||||
}
|
}
|
||||||
interface UseAuthReturn
|
interface UseAuthReturn extends CommonUseAuthReturn<typeof signIn, typeof signOut, typeof getSession, SessionData> {
|
||||||
extends CommonUseAuthReturn<
|
|
||||||
typeof signIn,
|
|
||||||
typeof signOut,
|
|
||||||
typeof getSession,
|
|
||||||
SessionData
|
|
||||||
> {
|
|
||||||
signUp: typeof signUp;
|
signUp: typeof signUp;
|
||||||
token: Readonly<Ref<string | null>>;
|
token: Readonly<Ref<string | null>>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user