diff --git a/src/extensions/chat/index.ts b/src/extensions/chat/index.ts
index daa07a3..97637f3 100644
--- a/src/extensions/chat/index.ts
+++ b/src/extensions/chat/index.ts
@@ -15,7 +15,7 @@ export default class extends ExtensionBase {
const message: message = {
name: ctx.context.user?.name,
pfp_code: ctx.context.user?.pfp_code,
- created_at: (new Date()).toLocaleTimeString('en-US', {hour12: false}),
+ created_at: (Date.now()),
content,
}
let userID = Number(ctx.context.user?.id)
diff --git a/src/extensions/chat/static/chat.js b/src/extensions/chat/static/chat.js
index 33ae4b8..c41f3d0 100644
--- a/src/extensions/chat/static/chat.js
+++ b/src/extensions/chat/static/chat.js
@@ -23,21 +23,39 @@ function sendMessage (e) {
e.target.message.value = ''
}
+let lastMessageDate
function addMessage(msg) {
function field(c) {
let f = document.createElement('span')
f.textContent = c
return f
}
+
+ const messageDate = new Date(msg.created_at); // Convert UNIX timestamp to Date
+ const messageDay = messageDate.toISOString().split('T', 1).at(0)
+
+ //ADD DAY SEPARATOR
+ if (messageDay !== lastMessageDate) {
+ const separator_row = messages.insertRow(-1)
+ separator_row.insertCell(-1)
+ const separator_col = separator_row.insertCell(-1)
+ const date_col = separator_col.appendChild(document.createElement('div'))
+ date_col.classList.add('separator')
+ date_col.appendChild(field(messageDay))
+ }
+
+
const row = messages.insertRow(-1)
const img_col = row.insertCell(-1)
img_col.innerHTML = `
`
const col = row.insertCell(-1)
const info_col = col.appendChild(document.createElement('div'))
info_col.appendChild(field(msg.name))
- info_col.appendChild(field(msg.created_at))
+ info_col.appendChild(field(messageDate.toLocaleTimeString('en-US', {hour12: false})))
const msg_col = col.appendChild(document.createElement('div'))
msg_col.appendChild(field(msg.content))
+
+ lastMessageDate = messageDay
}
function getHistory() {
diff --git a/src/extensions/chat/static/index.css b/src/extensions/chat/static/index.css
index f578f6e..657b2c2 100644
--- a/src/extensions/chat/static/index.css
+++ b/src/extensions/chat/static/index.css
@@ -91,6 +91,10 @@
width: fit-content;
}
+.separator {
+ margin: auto;
+}
+
/* Phones */
@media (max-width: 700px) {
diff --git a/src/extensions/invite/index.html b/src/extensions/invite/index.html
index 5f87456..d360296 100644
--- a/src/extensions/invite/index.html
+++ b/src/extensions/invite/index.html
@@ -10,9 +10,14 @@
| ID |
- Code |
+ Invite Code |
Created at |
- Used |
+ {% if user.is_admin %}
+ Created by |
+ Used by |
+ {% else %}
+ Used |
+ {% endif %}
@@ -21,7 +26,12 @@
{{link.id}} |
{{link.code}} |
{{link.created_at}} |
- {{"Yes" if link.used else "No"}} |
+ {% if user.is_admin %}
+ {{link.created_by}} |
+ {{link.used_by if link.used else "Not used"}} |
+ {% else %}
+ {{"Yes" if link.used else "No"}} |
+ {% endif %}
{% endfor %}
diff --git a/src/extensions/invite/index.ts b/src/extensions/invite/index.ts
index 67d7d33..269b01c 100644
--- a/src/extensions/invite/index.ts
+++ b/src/extensions/invite/index.ts
@@ -7,7 +7,6 @@ export default class extends ExtensionBase {
override name = 'invite'
override title = 'Invite'
override tables = true
- override hidden = true
salt: string
@@ -16,12 +15,6 @@ export default class extends ExtensionBase {
return ExtensionBase.init(this, context)
}
- override requires_admin: Extension['requires_admin'] = (path) => {
- if (['register', 'create_acc', 'register.css'].includes(path.at(0)??'')) {
- return false
- }
- return true
- }
override requires_login: Extension['requires_login'] = (path) => {
if (['register', 'create_acc', 'register.css'].includes(path.at(0)??'')) {
return false
@@ -35,14 +28,28 @@ export default class extends ExtensionBase {
switch (location) {
case '':
- case undefined:{
- let [invite_links, err] = await knex
- .query('_invite')
- .select('*')
- .then(unpack)
-
- ctx.context.invite_links = invite_links
- return this.return_html(ctx, 'index')
+ case undefined: {
+ if (ctx.context.user?.is_admin) {
+ let [invite_links, err] = await knex
+ .query('_invite')
+ .select('_invite.id', '_invite.code', '_invite.created_at', '_invite.used', 'a.name as used_by', 'b.name as created_by')
+ .leftJoin(knex.raw('user a'), '_invite.user_id', '=', 'a.id')
+ .leftJoin(knex.raw('user b'), '_invite.created_by', '=', 'b.id')
+ .then(unpack)
+
+ ctx.context.invite_links = invite_links
+ return this.return_html(ctx, 'index')
+ }else
+ {
+ let [invite_links, err] = await knex
+ .query('_invite')
+ .select('*')
+ .where('created_by', ctx.context.user?.id)
+ .then(unpack)
+
+ ctx.context.invite_links = invite_links
+ return this.return_html(ctx, 'index')
+ }
}
case 'create':{
@@ -55,7 +62,7 @@ export default class extends ExtensionBase {
let code = random_chars
await knex.query('_invite')
// @ts-expect-error
- .insert({code: code})
+ .insert({code: code, created_by: ctx.context.user?.id})
return this.return(ctx, undefined, location='/invite')
}
@@ -63,15 +70,8 @@ export default class extends ExtensionBase {
const invite_code = ctx.args.get('code')
if (!invite_code)
return
-
- let [invite, err] = await knex
- .query('_invite')
- .select('used')
- .where('code', invite_code)
- .first()
- .then(unpack)
-
- if (!err && !invite?.used){
+
+ if (await this.inviteCodeValid(invite_code)){
ctx.context.invite_code = invite_code
return this.return_html(ctx, 'register', undefined, 500, 200, {
"Set-Cookie": this.del_cookie('auth')
@@ -83,7 +83,8 @@ export default class extends ExtensionBase {
if (ctx.data)
{
let form: {invite_code?: string, username?: string, password?: string, minecraft_name?: string} = ctx.data.form
- if (form.username && form.password && form.invite_code) {
+ const valid_invite_code = await this.inviteCodeValid(form.invite_code)
+ if (form.username && form.password && valid_invite_code) {
form.username = form.username.substring(0, 32)
this.addUser(form.username, form.password, async (id?: number, err?: Error) => {
@@ -151,6 +152,24 @@ export default class extends ExtensionBase {
})
}
+ async inviteCodeValid(code?: string): Promise{
+ if (code === undefined)
+ return false
+ let [knex]: [Knex] = this.get_dependencies('Knex')
+
+ let [invite, err] = await knex
+ .query('_invite')
+ .select('used')
+ .where('code', code)
+ .first()
+ .then(unpack)
+
+ if (!err && !invite?.used)
+ return true
+ else
+ return false
+ }
+
private exists(name: User['name'], callback: (exists: boolean, err?: Error) => void): void {
let [knex]: [Knex] = this.get_dependencies('Knex')
// check if name already exists
diff --git a/src/extensions/invite/static/index.css b/src/extensions/invite/static/index.css
index b892790..ad92414 100644
--- a/src/extensions/invite/static/index.css
+++ b/src/extensions/invite/static/index.css
@@ -1,7 +1,7 @@
table {
- margin: 2%;
- padding-bottom: 5%;
+ margin: var(--margin-normal);
+ padding-bottom: 10px;
text-align: center;
font-size: smaller;
}
@@ -16,3 +16,9 @@ table th, td{
font-style: italic;
font-weight: lighter;
}
+
+@media (max-width: 550px) {
+ table {
+ margin: var(--margin-normal) auto;
+ }
+}
diff --git a/src/extensions/invite/tables.ts b/src/extensions/invite/tables.ts
index cefcdee..5c8b1f5 100644
--- a/src/extensions/invite/tables.ts
+++ b/src/extensions/invite/tables.ts
@@ -3,7 +3,7 @@ import { Knex } from '../../modules.ts'
export default class extends Tables {
override versions(versions: VersionMap) {
- versions.set('invite', 0)
+ versions.set('invite', 1)
return versions
}
@@ -24,6 +24,17 @@ export default class extends Tables {
// @ts-expect-error
.insert({code: 'admin'})
},
+ 1: async ()=>{
+ await knex.schema()
+ .alterTable('_invite', (table) => {
+ table.integer('created_by')
+ table.foreign('created_by', 'fk_user_id').references('_root_user.id')
+ })
+
+ await knex.query('_invite')
+ // @ts-expect-error
+ .update({created_by: 1})
+ },
})
return migrations