@@ -22,11 +22,15 @@ import type { InferSelectModel } from "drizzle-orm";
2222const connection = await mysql .createConnection ();
2323const db = drizzle (connection );
2424
25+ // your user table
2526export const userTable = mysqlTable (" user" , {
26- id: int (" id" ).primaryKey ().autoincrement ()
27+ id: int (" id" ).primaryKey ().autoincrement (),
28+ username: varchar (" username" , {
29+ length: 31
30+ }).notNull ()
2731});
2832
29- export const sessionTable = mysqlTable (" session " , {
33+ export const userSessionTable = mysqlTable (" user_session " , {
3034 id: varchar (" id" , {
3135 length: 255
3236 }).primaryKey (),
@@ -37,7 +41,7 @@ export const sessionTable = mysqlTable("session", {
3741});
3842
3943export type User = InferSelectModel <typeof userTable >;
40- export type Session = InferSelectModel <typeof sessionTable >;
44+ export type Session = InferSelectModel <typeof userSessionTable >;
4145```
4246
4347### PostgreSQL
@@ -52,11 +56,13 @@ import type { InferSelectModel } from "drizzle-orm";
5256const pool = new pg .Pool ();
5357const db = drizzle (pool );
5458
59+ // your user table
5560export const userTable = pgTable (" user" , {
56- id: serial (" id" ).primaryKey ()
61+ id: serial (" id" ).primaryKey (),
62+ username: text (" username" ).notNull ()
5763});
5864
59- export const sessionTable = pgTable (" session " , {
65+ export const userSessionTable = pgTable (" user_session " , {
6066 id: text (" id" ).primaryKey (),
6167 userId: integer (" user_id" )
6268 .notNull ()
@@ -68,7 +74,7 @@ export const sessionTable = pgTable("session", {
6874});
6975
7076export type User = InferSelectModel <typeof userTable >;
71- export type Session = InferSelectModel <typeof sessionTable >;
77+ export type Session = InferSelectModel <typeof userSessionTable >;
7278```
7379
7480### SQLite
@@ -83,11 +89,13 @@ import type { InferSelectModel } from "drizzle-orm";
8389const sqliteDB = sqlite (" :memory:" );
8490const db = drizzle (sqliteDB );
8591
92+ // your user table
8693export const userTable = sqliteTable (" user" , {
87- id: integer (" id" ).primaryKey ()
94+ id: integer (" id" ).primaryKey (),
95+ username: text (" username" ).notNull ()
8896});
8997
90- export const sessionTable = sqliteTable (" session " , {
98+ export const userSessionTable = sqliteTable (" user_session " , {
9199 id: text (" id" ).primaryKey (),
92100 userId: integer (" user_id" )
93101 .notNull ()
@@ -98,7 +106,7 @@ export const sessionTable = sqliteTable("session", {
98106});
99107
100108export type User = InferSelectModel <typeof userTable >;
101- export type Session = InferSelectModel <typeof sessionTable >;
109+ export type Session = InferSelectModel <typeof userSessionTable >;
102110```
103111
104112## Install dependencies
@@ -167,7 +175,7 @@ export function generateSessionToken(): string {
167175The session ID will be SHA-256 hash of the token. We'll set the expiration to 30 days.
168176
169177``` ts
170- import { db , userTable , sessionTable } from " ./db.js" ;
178+ import { db , userTable , userSessionTable } from " ./db.js" ;
171179import { eq } from " drizzle-orm" ;
172180import { encodeBase32LowerCaseNoPadding , encodeHexLowerCase } from " @oslojs/encoding" ;
173181import { sha256 } from " @oslojs/crypto/sha2" ;
@@ -181,7 +189,7 @@ export async function createSession(token: string, userId: number): Promise<Sess
181189 userId ,
182190 expiresAt: new Date (Date .now () + 1000 * 60 * 60 * 24 * 30 )
183191 };
184- await db .insert (sessionTable ).values (session );
192+ await db .insert (userSessionTable ).values (session );
185193 return session ;
186194}
187195```
@@ -196,7 +204,7 @@ We'll also extend the session expiration when it's close to expiration. This ens
196204For convenience, we'll return both the session and user object tied to the session ID.
197205
198206``` ts
199- import { db , userTable , sessionTable } from " ./db.js" ;
207+ import { db , userTable , userSessionTable } from " ./db.js" ;
200208import { eq } from " drizzle-orm" ;
201209import { encodeBase32LowerCaseNoPadding , encodeHexLowerCase } from " @oslojs/encoding" ;
202210import { sha256 } from " @oslojs/crypto/sha2" ;
@@ -206,26 +214,26 @@ import { sha256 } from "@oslojs/crypto/sha2";
206214export async function validateSessionToken(token : string ): Promise <SessionValidationResult > {
207215 const sessionId = encodeHexLowerCase (sha256 (new TextEncoder ().encode (token )));
208216 const result = await db
209- .select ({ user: userTable , session: sessionTable })
210- .from (sessionTable )
211- .innerJoin (userTable , eq (sessionTable .userId , userTable .id ))
212- .where (eq (sessionTable .id , sessionId ));
217+ .select ({ user: userTable , session: userSessionTable })
218+ .from (userSessionTable )
219+ .innerJoin (userTable , eq (userSessionTable .userId , userTable .id ))
220+ .where (eq (userSessionTable .id , sessionId ));
213221 if (result .length < 1 ) {
214222 return { session: null , user: null };
215223 }
216224 const { user, session } = result [0 ];
217225 if (Date .now () >= session .expiresAt .getTime ()) {
218- await db .delete (sessionTable ).where (eq (sessionTable .id , session .id ));
226+ await db .delete (userSessionTable ).where (eq (userSessionTable .id , session .id ));
219227 return { session: null , user: null };
220228 }
221229 if (Date .now () >= session .expiresAt .getTime () - 1000 * 60 * 60 * 24 * 15 ) {
222230 session .expiresAt = new Date (Date .now () + 1000 * 60 * 60 * 24 * 30 );
223231 await db
224- .update (sessionTable )
232+ .update (userSessionTable )
225233 .set ({
226234 expiresAt: session .expiresAt
227235 })
228- .where (eq (sessionTable .id , session .id ));
236+ .where (eq (userSessionTable .id , session .id ));
229237 }
230238 return { session , user };
231239}
@@ -234,24 +242,24 @@ export async function validateSessionToken(token: string): Promise<SessionValida
234242Finally, invalidate sessions by simply deleting it from the database.
235243
236244``` ts
237- import { db , userTable , sessionTable } from " ./db.js" ;
245+ import { db , userTable , userSessionTable } from " ./db.js" ;
238246import { eq } from " drizzle-orm" ;
239247
240248// ...
241249
242250export async function invalidateSession(sessionId : string ): Promise <void > {
243- await db .delete (sessionTable ).where (eq (sessionTable .id , sessionId ));
251+ await db .delete (userSessionTable ).where (eq (userSessionTable .id , sessionId ));
244252}
245253
246254export async function invalidateAllSessions(userId : number ): Promise <void > {
247- await db .delete (sessionTable ).where (eq (sessionTable .userId , userId ));
255+ await db .delete (userSessionTable ).where (eq (userSessionTable .userId , userId ));
248256}
249257```
250258
251259Here's the full code:
252260
253261``` ts
254- import { db , userTable , sessionTable } from " ./db.js" ;
262+ import { db , userTable , userSessionTable } from " ./db.js" ;
255263import { eq } from " drizzle-orm" ;
256264import { encodeBase32LowerCaseNoPadding , encodeHexLowerCase } from " @oslojs/encoding" ;
257265import { sha256 } from " @oslojs/crypto/sha2" ;
@@ -272,43 +280,43 @@ export async function createSession(token: string, userId: number): Promise<Sess
272280 userId ,
273281 expiresAt: new Date (Date .now () + 1000 * 60 * 60 * 24 * 30 )
274282 };
275- await db .insert (sessionTable ).values (session );
283+ await db .insert (userSessionTable ).values (session );
276284 return session ;
277285}
278286
279287export async function validateSessionToken(token : string ): Promise <SessionValidationResult > {
280288 const sessionId = encodeHexLowerCase (sha256 (new TextEncoder ().encode (token )));
281289 const result = await db
282- .select ({ user: userTable , session: sessionTable })
283- .from (sessionTable )
284- .innerJoin (userTable , eq (sessionTable .userId , userTable .id ))
285- .where (eq (sessionTable .id , sessionId ));
290+ .select ({ user: userTable , session: userSessionTable })
291+ .from (userSessionTable )
292+ .innerJoin (userTable , eq (userSessionTable .userId , userTable .id ))
293+ .where (eq (userSessionTable .id , sessionId ));
286294 if (result .length < 1 ) {
287295 return { session: null , user: null };
288296 }
289297 const { user, session } = result [0 ];
290298 if (Date .now () >= session .expiresAt .getTime ()) {
291- await db .delete (sessionTable ).where (eq (sessionTable .id , session .id ));
299+ await db .delete (userSessionTable ).where (eq (userSessionTable .id , session .id ));
292300 return { session: null , user: null };
293301 }
294302 if (Date .now () >= session .expiresAt .getTime () - 1000 * 60 * 60 * 24 * 15 ) {
295303 session .expiresAt = new Date (Date .now () + 1000 * 60 * 60 * 24 * 30 );
296304 await db
297- .update (sessionTable )
305+ .update (userSessionTable )
298306 .set ({
299307 expiresAt: session .expiresAt
300308 })
301- .where (eq (sessionTable .id , session .id ));
309+ .where (eq (userSessionTable .id , session .id ));
302310 }
303311 return { session , user };
304312}
305313
306314export async function invalidateSession(sessionId : string ): Promise <void > {
307- await db .delete (sessionTable ).where (eq (sessionTable .id , sessionId ));
315+ await db .delete (userSessionTable ).where (eq (userSessionTable .id , sessionId ));
308316}
309317
310318export async function invalidateAllSessions(userId : number ): Promise <void > {
311- await db .delete (sessionTable ).where (eq (sessionTable .userId , userId ));
319+ await db .delete (userSessionTable ).where (eq (userSessionTable .userId , userId ));
312320}
313321
314322export type SessionValidationResult =
0 commit comments