diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts
index 0cb885fa..1ab75a5a 100644
--- a/util/src/entities/BaseClass.ts
+++ b/util/src/entities/BaseClass.ts
@@ -1,11 +1,12 @@
import "reflect-metadata";
-import { BaseEntity, EntityMetadata, ObjectIdColumn, PrimaryColumn, FindOptionsWhere } from "typeorm";
+import { BaseEntity, EntityMetadata, ObjectIdColumn, PrimaryColumn, FindOptionsWhere, Generated, SaveOptions } from "typeorm";
import { Snowflake } from "../util/Snowflake";
export class BaseClassWithoutId extends BaseEntity {
constructor(props?: any) {
super();
- this.assign(props);
+ if(props != undefined && props != null && Object.keys(props).length > 0)
+ this.assign(props);
}
assign(props: any = {}) {
@@ -13,8 +14,11 @@ export class BaseClassWithoutId extends BaseEntity {
delete props.opts;
delete props.props;
// will not include relational properties
-
- for (const key in props) {
+ console.warn("WARNING: BaseClass.assign called! This will probably fail!");
+ console.warn(this)
+ Object.assign(this,props);
+ if(/--debug|--inspect/.test(process.execArgv.join(' '))) debugger;
+ /*for (const key in props) {
// @ts-ignore
const setter = this[`set${key.capitalize()}`]; // use setter function if it exists
@@ -24,7 +28,7 @@ export class BaseClassWithoutId extends BaseEntity {
// @ts-ignore
this[key] = props[key];
}
- }
+ }*/
}
}
@@ -35,8 +39,13 @@ export class BaseClass extends BaseClassWithoutId {
id: string;
assign(props: any = {}) {
- super.assign(props);
+ super.assign(props);
if (!this.id) this.id = Snowflake.generate();
return this;
}
+
+ save(options?: SaveOptions | undefined): Promise<this> {
+ if (!this.id) this.id = Snowflake.generate();
+ return super.save(options);
+ }
}
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index 5ccb43ce..a7ca647b 100644
--- a/util/src/entities/Channel.ts
+++ b/util/src/entities/Channel.ts
@@ -222,7 +222,7 @@ export class Channel extends BaseClass {
};
await Promise.all([
- new Channel(channel).save(),
+ Object.assign(new Channel(),channel).save(),
!opts?.skipEventEmit
? emitEvent({
event: "CHANNEL_CREATE",
@@ -263,7 +263,8 @@ export class Channel extends BaseClass {
if (containsAll(re, channelRecipients)) {
if (channel == null) {
channel = ur.channel;
- await ur.assign({ closed: false }).save();
+ ur = Object.assign(ur, { closed: false });
+ await ur.save();
}
}
}
@@ -272,7 +273,7 @@ export class Channel extends BaseClass {
if (channel == null) {
name = trimSpecial(name);
- channel = await new Channel({
+ channel = await (Object.assign(new Channel(), {
name,
type,
owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server
@@ -280,9 +281,9 @@ export class Channel extends BaseClass {
last_message_id: null,
recipients: channelRecipients.map(
(x) =>
- new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })
+ Object.assign(new Recipient(), { user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })
),
- }).save();
+ }) as Channel).save();
}
const channel_dto = await DmChannelDTO.from(channel);
diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts
index c84ea4aa..901a5e54 100644
--- a/util/src/entities/Config.ts
+++ b/util/src/entities/Config.ts
@@ -129,6 +129,7 @@ export interface ConfigValue {
requireCaptcha: boolean;
};
register: {
+ defaultRights: string;
email: {
required: boolean;
allowlist: boolean;
@@ -349,6 +350,7 @@ export const DefaultConfigOptions: ConfigValue = {
minSymbols: 0,
},
incrementingDiscriminators: false,
+ defaultRights: "0"
},
regions: {
default: "fosscord",
diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts
index 328c586e..058033e8 100644
--- a/util/src/entities/Guild.ts
+++ b/util/src/entities/Guild.ts
@@ -285,7 +285,7 @@ export class Guild extends BaseClass {
}) {
const guild_id = Snowflake.generate();
- const guild = await new Guild({
+ const guild: Guild = Object.assign(new Guild(),{
name: body.name || "Fosscord",
icon: await handleFile(`/icons/${guild_id}`, body.icon as string),
region: Config.get().regions.default,
@@ -316,11 +316,12 @@ export class Guild extends BaseClass {
welcome_channels: [],
},
widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions
- }).save();
+ });
+ await guild.save();
// we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error
// TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage
- await new Role({
+ let role: Role = Object.assign(new Role(), {
id: guild_id,
guild_id: guild_id,
color: 0,
@@ -333,7 +334,8 @@ export class Guild extends BaseClass {
position: 0,
icon: null,
unicode_emoji: null
- }).save();
+ });
+ await role.save();
if (!body.channels || !body.channels.length) body.channels = [{ id: "01", type: 0, name: "general" }];
diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts
index 7ca50992..e4aa8331 100644
--- a/util/src/entities/Member.ts
+++ b/util/src/entities/Member.ts
@@ -85,8 +85,8 @@ export class Member extends BaseClassWithoutId {
@Column()
joined_at: Date;
- @Column({ type: "bigint", nullable: true })
- premium_since?: number;
+ @Column({ nullable: true })
+ premium_since?: Date;
@Column()
deaf: boolean;
@@ -161,7 +161,7 @@ export class Member extends BaseClassWithoutId {
}),
Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }),
]);
- member.roles.push(new Role({ id: role_id }));
+ member.roles.push(Object.assign(new Role(), { id: role_id }));
await Promise.all([
member.save(),
@@ -264,9 +264,9 @@ export class Member extends BaseClassWithoutId {
//TODO: check for bugs
if(guild.member_count) guild.member_count++;
await Promise.all([
- new Member({
+ Object.assign(new Member(), {
...member,
- roles: [new Role({ id: guild_id })],
+ roles: [Object.assign(new Role(), { id: guild_id })],
// read_state: {},
settings: {
channel_overrides: [],
diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts
index 7d5dc5a6..81017c2d 100644
--- a/util/src/entities/User.ts
+++ b/util/src/entities/User.ts
@@ -255,7 +255,7 @@ export class User extends BaseClass {
// if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false
const language = req.language === "en" ? "en-US" : req.language || "en-US";
- const user = new User({
+ const user = Object.assign(new User(), {
created_at: new Date(),
username: username,
discriminator,
@@ -275,7 +275,7 @@ export class User extends BaseClass {
disabled: false,
deleted: false,
email: email,
- rights: "0", // TODO: grant rights correctly, as 0 actually stands for no rights at all
+ rights: Config.get().register.defaultRights, // TODO: grant rights correctly, as 0 actually stands for no rights at all
nsfw_allowed: true, // TODO: depending on age
public_flags: "0",
flags: "0", // TODO: generate
@@ -289,6 +289,8 @@ export class User extends BaseClass {
notes: {},
});
+ console.log("new user")
+ console.log(user);
await user.save();
setImmediate(async () => {
diff --git a/util/src/migrations/mariadb/1659921859145-premium_since_as_date.ts b/util/src/migrations/mariadb/1659921859145-premium_since_as_date.ts
new file mode 100644
index 00000000..de173cfe
--- /dev/null
+++ b/util/src/migrations/mariadb/1659921859145-premium_since_as_date.ts
@@ -0,0 +1,26 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class premiumSinceAsDate1659921859145 implements MigrationInterface {
+ name = 'premiumSinceAsDate1659921859145'
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ ALTER TABLE \`members\` DROP COLUMN \`premium_since\`
+ `);
+ await queryRunner.query(`
+ ALTER TABLE \`members\`
+ ADD \`premium_since\` datetime NULL
+ `);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ ALTER TABLE \`members\` DROP COLUMN \`premium_since\`
+ `);
+ await queryRunner.query(`
+ ALTER TABLE \`members\`
+ ADD \`premium_since\` bigint NULL
+ `);
+ }
+
+}
diff --git a/util/src/migrations/postgres/1659921826567-premium_since_as_date.ts b/util/src/migrations/postgres/1659921826567-premium_since_as_date.ts
new file mode 100644
index 00000000..ac1e2edb
--- /dev/null
+++ b/util/src/migrations/postgres/1659921826567-premium_since_as_date.ts
@@ -0,0 +1,26 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class premiumSinceAsDate1659921826567 implements MigrationInterface {
+ name = 'premiumSinceAsDate1659921826567'
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ ALTER TABLE "members" DROP COLUMN "premium_since"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "members"
+ ADD "premium_since" TIMESTAMP
+ `);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ ALTER TABLE "members" DROP COLUMN "premium_since"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "members"
+ ADD "premium_since" bigint
+ `);
+ }
+
+}
diff --git a/util/src/migrations/sqlite/1659921722863-premium_since_as_date.ts b/util/src/migrations/sqlite/1659921722863-premium_since_as_date.ts
new file mode 100644
index 00000000..788be625
--- /dev/null
+++ b/util/src/migrations/sqlite/1659921722863-premium_since_as_date.ts
@@ -0,0 +1,252 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class premiumSinceAsDate1659921722863 implements MigrationInterface {
+ name = 'premiumSinceAsDate1659921722863'
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3"
+ `);
+ await queryRunner.query(`
+ CREATE TABLE "temporary_members" (
+ "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ "id" varchar NOT NULL,
+ "guild_id" varchar NOT NULL,
+ "nick" varchar,
+ "joined_at" datetime NOT NULL,
+ "premium_since" bigint,
+ "deaf" boolean NOT NULL,
+ "mute" boolean NOT NULL,
+ "pending" boolean NOT NULL,
+ "settings" text NOT NULL,
+ "last_message_id" varchar,
+ "joined_by" varchar,
+ CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
+ CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION
+ )
+ `);
+ await queryRunner.query(`
+ INSERT INTO "temporary_members"(
+ "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ )
+ SELECT "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ FROM "members"
+ `);
+ await queryRunner.query(`
+ DROP TABLE "members"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "temporary_members"
+ RENAME TO "members"
+ `);
+ await queryRunner.query(`
+ CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id")
+ `);
+ await queryRunner.query(`
+ DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3"
+ `);
+ await queryRunner.query(`
+ CREATE TABLE "temporary_members" (
+ "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ "id" varchar NOT NULL,
+ "guild_id" varchar NOT NULL,
+ "nick" varchar,
+ "joined_at" datetime NOT NULL,
+ "premium_since" datetime,
+ "deaf" boolean NOT NULL,
+ "mute" boolean NOT NULL,
+ "pending" boolean NOT NULL,
+ "settings" text NOT NULL,
+ "last_message_id" varchar,
+ "joined_by" varchar,
+ CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
+ CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION
+ )
+ `);
+ await queryRunner.query(`
+ INSERT INTO "temporary_members"(
+ "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ )
+ SELECT "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ FROM "members"
+ `);
+ await queryRunner.query(`
+ DROP TABLE "members"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "temporary_members"
+ RENAME TO "members"
+ `);
+ await queryRunner.query(`
+ CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id")
+ `);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`
+ DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "members"
+ RENAME TO "temporary_members"
+ `);
+ await queryRunner.query(`
+ CREATE TABLE "members" (
+ "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ "id" varchar NOT NULL,
+ "guild_id" varchar NOT NULL,
+ "nick" varchar,
+ "joined_at" datetime NOT NULL,
+ "premium_since" bigint,
+ "deaf" boolean NOT NULL,
+ "mute" boolean NOT NULL,
+ "pending" boolean NOT NULL,
+ "settings" text NOT NULL,
+ "last_message_id" varchar,
+ "joined_by" varchar,
+ CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
+ CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION
+ )
+ `);
+ await queryRunner.query(`
+ INSERT INTO "members"(
+ "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ )
+ SELECT "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ FROM "temporary_members"
+ `);
+ await queryRunner.query(`
+ DROP TABLE "temporary_members"
+ `);
+ await queryRunner.query(`
+ CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id")
+ `);
+ await queryRunner.query(`
+ DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3"
+ `);
+ await queryRunner.query(`
+ ALTER TABLE "members"
+ RENAME TO "temporary_members"
+ `);
+ await queryRunner.query(`
+ CREATE TABLE "members" (
+ "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ "id" varchar NOT NULL,
+ "guild_id" varchar NOT NULL,
+ "nick" varchar,
+ "joined_at" datetime NOT NULL,
+ "premium_since" bigint,
+ "deaf" boolean NOT NULL,
+ "mute" boolean NOT NULL,
+ "pending" boolean NOT NULL,
+ "settings" text NOT NULL,
+ "last_message_id" varchar,
+ "joined_by" varchar,
+ CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
+ CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION
+ )
+ `);
+ await queryRunner.query(`
+ INSERT INTO "members"(
+ "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ )
+ SELECT "index",
+ "id",
+ "guild_id",
+ "nick",
+ "joined_at",
+ "premium_since",
+ "deaf",
+ "mute",
+ "pending",
+ "settings",
+ "last_message_id",
+ "joined_by"
+ FROM "temporary_members"
+ `);
+ await queryRunner.query(`
+ DROP TABLE "temporary_members"
+ `);
+ await queryRunner.query(`
+ CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id")
+ `);
+ }
+
+}
diff --git a/util/src/util/BitField.ts b/util/src/util/BitField.ts
index fb887e05..9bdbf6d7 100644
--- a/util/src/util/BitField.ts
+++ b/util/src/util/BitField.ts
@@ -138,6 +138,9 @@ export class BitField {
return bit.map((p) => resolve.call(this, p)).reduce((prev, p) => BigInt(prev) | BigInt(p), BigInt(0));
}
if (typeof bit === "string" && typeof FLAGS[bit] !== "undefined") return FLAGS[bit];
+ if (bit === "0") return BigInt(0); //special case: 0
+ if (typeof bit === "string") return BigInt(bit); //last ditch effort...
+ if(/--debug|--inspect/.test(process.execArgv.join(' '))) debugger; //if you're here, we have an invalid bitfield... if bit is 0, thats fine, I guess...
throw new RangeError("BITFIELD_INVALID: " + bit);
}
}
|