Skip to content

Commit 93da280

Browse files
committed
FEAT: use sepearate db users for migrations and tenant operations
1 parent ea0526f commit 93da280

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

env.sample

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
# Superuser for migrations
2+
POSTGRES_ADMIN_USER=postgres
3+
POSTGRES_ADMIN_PASSWORD=postgres
4+
# Minimal user with restricted access
5+
POSTGRES_TENANT_USER=tenant
6+
POSTGRES_TENANT_PASSWORD=tenant
17
POSTGRES_HOST=localhost
28
POSTGRES_PORT=5432
3-
POSTGRES_USER=postgres
4-
POSTGRES_PASSWORD=postgres
59
POSTGRES_DB=authentication-service
610
POSTGRES_TENANT_MAX_CONNECTION_LIMIT=10
711
REDIS_HOST=localhost

src/config/migration.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ const dataSource = new DataSource({
1010
host: process.env.POSTGRES_HOST,
1111
port: parseInt(process.env.POSTGRES_PORT as string),
1212
database: process.env.POSTGRES_DB,
13-
username: process.env.POSTGRES_USER,
14-
password: process.env.POSTGRES_PASSWORD,
13+
username: process.env.POSTGRES_ADMIN_USER,
14+
password: process.env.POSTGRES_ADMIN_PASSWORD,
1515
synchronize: false,
1616
logging: false,
1717
namingStrategy: new SnakeNamingStrategy(),

src/util/database.connection.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export async function getConnectionForTenant(
3131
type: 'postgres',
3232
host: process.env.POSTGRES_HOST,
3333
port: Number(process.env.POSTGRES_PORT),
34-
username: process.env.POSTGRES_USER,
35-
password: process.env.POSTGRES_PASSWORD,
34+
username: process.env.POSTGRES_TENANT_USER,
35+
password: process.env.POSTGRES_TENANT_PASSWORD,
3636
database: process.env.POSTGRES_DB,
3737
entities: [
3838
__dirname + '/../**/*.entity.ts',
@@ -68,3 +68,30 @@ const switchToTenant = async (
6868
);
6969
}
7070
};
71+
72+
export async function getConnectionAsOwner(): Promise<DataSource> {
73+
if (!getConnectionManager().has('Owner'))
74+
return await new DataSource({
75+
name: 'Owner',
76+
type: 'postgres',
77+
host: process.env.POSTGRES_HOST,
78+
port: Number(process.env.POSTGRES_PORT),
79+
username: process.env.POSTGRES_ADMIN_USER,
80+
password: process.env.POSTGRES_ADMIN_PASSWORD,
81+
database: process.env.POSTGRES_DB,
82+
entities: [__dirname + '/../**/*.entity.js'],
83+
synchronize: false,
84+
logging: ['error'],
85+
namingStrategy: new SnakeNamingStrategy(),
86+
migrationsTableName: 'migrations',
87+
migrations: [__dirname + '/../migrations/*.js'],
88+
...(process.env.POSTGRES_ADMIN_MAX_CONNECTION_LIMIT
89+
? { extra: { max: process.env.POSTGRES_ADMIN_MAX_CONNECTION_LIMIT } }
90+
: {}),
91+
}).initialize();
92+
const con = getConnectionManager().get('Owner');
93+
const existingConnection = await Promise.resolve(
94+
con.isConnected ? con : con.connect(),
95+
);
96+
return existingConnection;
97+
}

0 commit comments

Comments
 (0)