@tyravel/auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/auth-manager.d.ts +27 -0
  2. package/dist/auth-manager.d.ts.map +1 -0
  3. package/dist/auth-manager.js +102 -0
  4. package/dist/auth-manager.js.map +1 -0
  5. package/dist/auth.test.d.ts +2 -0
  6. package/dist/auth.test.d.ts.map +1 -0
  7. package/dist/auth.test.js +67 -0
  8. package/dist/auth.test.js.map +1 -0
  9. package/dist/authorization-exceptions.d.ts +7 -0
  10. package/dist/authorization-exceptions.d.ts.map +1 -0
  11. package/dist/authorization-exceptions.js +13 -0
  12. package/dist/authorization-exceptions.js.map +1 -0
  13. package/dist/exceptions.d.ts +7 -0
  14. package/dist/exceptions.d.ts.map +1 -0
  15. package/dist/exceptions.js +13 -0
  16. package/dist/exceptions.js.map +1 -0
  17. package/dist/gate.d.ts +16 -0
  18. package/dist/gate.d.ts.map +1 -0
  19. package/dist/gate.js +66 -0
  20. package/dist/gate.js.map +1 -0
  21. package/dist/gate.test.d.ts +2 -0
  22. package/dist/gate.test.d.ts.map +1 -0
  23. package/dist/gate.test.js +33 -0
  24. package/dist/gate.test.js.map +1 -0
  25. package/dist/hasher.d.ts +5 -0
  26. package/dist/hasher.d.ts.map +1 -0
  27. package/dist/hasher.js +28 -0
  28. package/dist/hasher.js.map +1 -0
  29. package/dist/index.d.ts +18 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +15 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/oauth.d.ts +40 -0
  34. package/dist/oauth.d.ts.map +1 -0
  35. package/dist/oauth.js +178 -0
  36. package/dist/oauth.js.map +1 -0
  37. package/dist/oauth.test.d.ts +2 -0
  38. package/dist/oauth.test.d.ts.map +1 -0
  39. package/dist/oauth.test.js +17 -0
  40. package/dist/oauth.test.js.map +1 -0
  41. package/dist/password-reset-broker.d.ts +20 -0
  42. package/dist/password-reset-broker.d.ts.map +1 -0
  43. package/dist/password-reset-broker.js +68 -0
  44. package/dist/password-reset-broker.js.map +1 -0
  45. package/dist/personal-access-token-repository.d.ts +14 -0
  46. package/dist/personal-access-token-repository.d.ts.map +1 -0
  47. package/dist/personal-access-token-repository.js +55 -0
  48. package/dist/personal-access-token-repository.js.map +1 -0
  49. package/dist/policy.d.ts +3 -0
  50. package/dist/policy.d.ts.map +1 -0
  51. package/dist/policy.js +3 -0
  52. package/dist/policy.js.map +1 -0
  53. package/dist/session-guard.d.ts +26 -0
  54. package/dist/session-guard.d.ts.map +1 -0
  55. package/dist/session-guard.js +118 -0
  56. package/dist/session-guard.js.map +1 -0
  57. package/dist/session-store.d.ts +18 -0
  58. package/dist/session-store.d.ts.map +1 -0
  59. package/dist/session-store.js +69 -0
  60. package/dist/session-store.js.map +1 -0
  61. package/dist/session.d.ts +18 -0
  62. package/dist/session.d.ts.map +1 -0
  63. package/dist/session.js +33 -0
  64. package/dist/session.js.map +1 -0
  65. package/dist/token-guard.d.ts +20 -0
  66. package/dist/token-guard.d.ts.map +1 -0
  67. package/dist/token-guard.js +51 -0
  68. package/dist/token-guard.js.map +1 -0
  69. package/dist/token.test.d.ts +2 -0
  70. package/dist/token.test.d.ts.map +1 -0
  71. package/dist/token.test.js +11 -0
  72. package/dist/token.test.js.map +1 -0
  73. package/dist/types.d.ts +73 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/dist/user-provider.d.ts +15 -0
  78. package/dist/user-provider.d.ts.map +1 -0
  79. package/dist/user-provider.js +30 -0
  80. package/dist/user-provider.js.map +1 -0
  81. package/package.json +41 -0
@@ -0,0 +1,69 @@
1
+ import { QueryBuilder } from '@tyravel/database';
2
+ export class DatabaseSessionStore {
3
+ connection;
4
+ table;
5
+ constructor(connection, table = 'sessions') {
6
+ this.connection = connection;
7
+ this.table = table;
8
+ }
9
+ async read(id) {
10
+ const row = await new QueryBuilder(this.connection, this.table)
11
+ .where('id', id)
12
+ .first();
13
+ if (!row) {
14
+ return {};
15
+ }
16
+ try {
17
+ return JSON.parse(row.payload);
18
+ }
19
+ catch {
20
+ return {};
21
+ }
22
+ }
23
+ async write(id, data, lifetimeMinutes) {
24
+ const now = Math.floor(Date.now() / 1000);
25
+ const payload = JSON.stringify(data);
26
+ const existing = await new QueryBuilder(this.connection, this.table)
27
+ .where('id', id)
28
+ .first();
29
+ if (existing) {
30
+ await new QueryBuilder(this.connection, this.table)
31
+ .where('id', id)
32
+ .update({
33
+ payload,
34
+ last_activity: now,
35
+ });
36
+ return;
37
+ }
38
+ await new QueryBuilder(this.connection, this.table).insert({
39
+ id,
40
+ payload,
41
+ last_activity: now,
42
+ user_id: data['auth.user_id'] ?? null,
43
+ ip_address: null,
44
+ user_agent: null,
45
+ });
46
+ }
47
+ async destroy(id) {
48
+ await new QueryBuilder(this.connection, this.table).where('id', id).delete();
49
+ }
50
+ async pruneExpired(lifetimeMinutes) {
51
+ const cutoff = Math.floor(Date.now() / 1000) - lifetimeMinutes * 60;
52
+ await new QueryBuilder(this.connection, this.table)
53
+ .where('last_activity', '<', cutoff)
54
+ .delete();
55
+ }
56
+ }
57
+ export class MemorySessionStore {
58
+ sessions = new Map();
59
+ async read(id) {
60
+ return { ...(this.sessions.get(id) ?? {}) };
61
+ }
62
+ async write(id, data, _lifetimeMinutes) {
63
+ this.sessions.set(id, { ...data });
64
+ }
65
+ async destroy(id) {
66
+ this.sessions.delete(id);
67
+ }
68
+ }
69
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface SessionStore {
2
+ read(id: string): Promise<Record<string, unknown>>;
3
+ write(id: string, data: Record<string, unknown>, lifetimeMinutes: number): Promise<void>;
4
+ destroy(id: string): Promise<void>;
5
+ }
6
+ export declare class Session {
7
+ readonly id: string;
8
+ private data;
9
+ private dirty;
10
+ constructor(id: string, data: Record<string, unknown>);
11
+ get<T = unknown>(key: string, fallback?: T): T | undefined;
12
+ put(key: string, value: unknown): this;
13
+ forget(key: string): this;
14
+ all(): Record<string, unknown>;
15
+ isDirty(): boolean;
16
+ markClean(): void;
17
+ }
18
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,qBAAa,OAAO;aAIA,EAAE,EAAE,MAAM;IAC1B,OAAO,CAAC,IAAI;IAJd,OAAO,CAAC,KAAK,CAAS;gBAGJ,EAAE,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAGvC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAK1D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAMtC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzB,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI9B,OAAO,IAAI,OAAO;IAIlB,SAAS,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,33 @@
1
+ export class Session {
2
+ id;
3
+ data;
4
+ dirty = false;
5
+ constructor(id, data) {
6
+ this.id = id;
7
+ this.data = data;
8
+ }
9
+ get(key, fallback) {
10
+ const value = this.data[key];
11
+ return (value === undefined ? fallback : value);
12
+ }
13
+ put(key, value) {
14
+ this.data[key] = value;
15
+ this.dirty = true;
16
+ return this;
17
+ }
18
+ forget(key) {
19
+ delete this.data[key];
20
+ this.dirty = true;
21
+ return this;
22
+ }
23
+ all() {
24
+ return { ...this.data };
25
+ }
26
+ isDirty() {
27
+ return this.dirty;
28
+ }
29
+ markClean() {
30
+ this.dirty = false;
31
+ }
32
+ }
33
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,OAAO;IAIA;IACR;IAJF,KAAK,GAAG,KAAK,CAAC;IAEtB,YACkB,EAAU,EAClB,IAA6B;QADrB,OAAE,GAAF,EAAE,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAyB;IACpC,CAAC;IAEJ,GAAG,CAAc,GAAW,EAAE,QAAY;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAkB,CAAC;IACnE,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAc;QAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG;QACD,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import type { TyravelRequest } from '@tyravel/http';
2
+ import type { Authenticatable, Guard } from './types.js';
3
+ import type { UserProvider } from './user-provider.js';
4
+ import { PersonalAccessTokenRepository } from './personal-access-token-repository.js';
5
+ export declare class TokenGuard implements Guard {
6
+ private readonly provider;
7
+ private readonly tokens;
8
+ readonly name: string;
9
+ private request?;
10
+ private currentUser;
11
+ private resolved;
12
+ constructor(name: string, provider: UserProvider, tokens: PersonalAccessTokenRepository);
13
+ setRequest(request: TyravelRequest): void;
14
+ user(): Authenticatable | null;
15
+ id(): string | number | null;
16
+ check(): Promise<boolean>;
17
+ authenticate(): Promise<Authenticatable | null>;
18
+ private resolve;
19
+ }
20
+ //# sourceMappingURL=token-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-guard.d.ts","sourceRoot":"","sources":["../src/token-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF,qBAAa,UAAW,YAAW,KAAK;IAQpC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IARzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,OAAO,CAAC,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,QAAQ,CAAS;gBAGvB,IAAI,EAAE,MAAM,EACK,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,6BAA6B;IAKxD,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAMzC,IAAI,IAAI,eAAe,GAAG,IAAI;IAI9B,EAAE,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI;IAItB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAKzB,YAAY,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAKvC,OAAO;CAwBtB"}
@@ -0,0 +1,51 @@
1
+ export class TokenGuard {
2
+ provider;
3
+ tokens;
4
+ name;
5
+ request;
6
+ currentUser = null;
7
+ resolved = false;
8
+ constructor(name, provider, tokens) {
9
+ this.provider = provider;
10
+ this.tokens = tokens;
11
+ this.name = name;
12
+ }
13
+ setRequest(request) {
14
+ this.request = request;
15
+ this.currentUser = null;
16
+ this.resolved = false;
17
+ }
18
+ user() {
19
+ return this.currentUser;
20
+ }
21
+ id() {
22
+ return this.currentUser?.getAuthIdentifier() ?? null;
23
+ }
24
+ async check() {
25
+ await this.resolve();
26
+ return this.currentUser !== null;
27
+ }
28
+ async authenticate() {
29
+ await this.resolve();
30
+ return this.currentUser;
31
+ }
32
+ async resolve() {
33
+ if (this.resolved || !this.request) {
34
+ return;
35
+ }
36
+ this.resolved = true;
37
+ const header = this.request.header('authorization');
38
+ if (!header?.toLowerCase().startsWith('bearer ')) {
39
+ return;
40
+ }
41
+ const bearer = header.slice(7).trim();
42
+ if (!bearer) {
43
+ return;
44
+ }
45
+ this.currentUser = await this.tokens.findUserIdByBearerToken(bearer, (id) => this.provider.retrieveById(id));
46
+ if (this.currentUser) {
47
+ this.request.user = this.currentUser;
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=token-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-guard.js","sourceRoot":"","sources":["../src/token-guard.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,UAAU;IAQF;IACA;IARV,IAAI,CAAS;IACd,OAAO,CAAkB;IACzB,WAAW,GAA2B,IAAI,CAAC;IAC3C,QAAQ,GAAG,KAAK,CAAC;IAEzB,YACE,IAAY,EACK,QAAsB,EACtB,MAAqC;QADrC,aAAQ,GAAR,QAAQ,CAAc;QACtB,WAAM,GAAN,MAAM,CAA+B;QAEtD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,UAAU,CAAC,OAAuB;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,EAAE;QACA,OAAO,IAAI,CAAC,WAAW,EAAE,iBAAiB,EAAE,IAAI,IAAI,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAC1E,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAC/B,CAAC;QAEF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;QACvC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=token.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.test.d.ts","sourceRoot":"","sources":["../src/token.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createHash } from 'node:crypto';
3
+ function hashToken(token) {
4
+ return createHash('sha256').update(token).digest('hex');
5
+ }
6
+ describe('API token hashing', () => {
7
+ it('uses sha256 for storage', () => {
8
+ expect(hashToken('plain-token')).toBe(createHash('sha256').update('plain-token').digest('hex'));
9
+ });
10
+ });
11
+ //# sourceMappingURL=token.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.test.js","sourceRoot":"","sources":["../src/token.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CACnC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,73 @@
1
+ import type { Model } from '@tyravel/database';
2
+ import type { TyravelRequest } from '@tyravel/http';
3
+ import type { Constructor } from '@tyravel/container';
4
+ import type { Policy } from './policy.js';
5
+ export interface Authenticatable {
6
+ getAuthIdentifier(): string | number;
7
+ getAuthPassword(): string;
8
+ }
9
+ export type UserModelConstructor = new (attributes?: Record<string, unknown>) => Model & Authenticatable;
10
+ export interface SessionGuardConfig {
11
+ driver: 'session';
12
+ provider: string;
13
+ }
14
+ export interface TokenGuardConfig {
15
+ driver: 'token';
16
+ provider: string;
17
+ hashKey?: string;
18
+ }
19
+ export type GuardConfig = SessionGuardConfig | TokenGuardConfig;
20
+ export interface EloquentUserProviderConfig {
21
+ driver: 'eloquent';
22
+ model: UserModelConstructor;
23
+ }
24
+ export interface PasswordBrokerConfig {
25
+ provider: string;
26
+ table: string;
27
+ expireMinutes: number;
28
+ connection?: string;
29
+ }
30
+ export interface OAuthProviderConfig {
31
+ clientId: string;
32
+ clientSecret: string;
33
+ redirectUri: string;
34
+ scopes?: string[];
35
+ }
36
+ export interface AuthConfig {
37
+ defaults: {
38
+ guard: string;
39
+ };
40
+ guards: Record<string, GuardConfig>;
41
+ providers: Record<string, EloquentUserProviderConfig>;
42
+ session: {
43
+ cookie: string;
44
+ lifetimeMinutes: number;
45
+ table: string;
46
+ connection?: string;
47
+ };
48
+ passwords?: Record<string, PasswordBrokerConfig>;
49
+ oauth?: {
50
+ providers: Record<string, OAuthProviderConfig>;
51
+ accountsTable?: string;
52
+ connection?: string;
53
+ };
54
+ policies?: Record<string, PolicyConstructor>;
55
+ tokens?: {
56
+ table: string;
57
+ connection?: string;
58
+ };
59
+ }
60
+ export interface Guard {
61
+ readonly name: string;
62
+ setRequest(request: TyravelRequest): void;
63
+ user(): Authenticatable | null;
64
+ id(): string | number | null;
65
+ check(): boolean | Promise<boolean>;
66
+ }
67
+ export type PolicyConstructor = Constructor<Policy>;
68
+ export interface NewAccessToken {
69
+ plainTextToken: string;
70
+ name: string;
71
+ abilities: string[];
72
+ }
73
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import type { Authenticatable, UserModelConstructor } from './types.js';
2
+ export interface UserProvider {
3
+ retrieveById(id: string | number): Promise<Authenticatable | null>;
4
+ retrieveByCredentials(credentials: Record<string, string>): Promise<Authenticatable | null>;
5
+ validateCredentials(user: Authenticatable, credentials: Record<string, string>): Promise<boolean>;
6
+ }
7
+ export declare class EloquentUserProvider implements UserProvider {
8
+ private readonly model;
9
+ private readonly hasher;
10
+ constructor(model: UserModelConstructor);
11
+ retrieveById(id: string | number): Promise<Authenticatable | null>;
12
+ retrieveByCredentials(credentials: Record<string, string>): Promise<Authenticatable | null>;
13
+ validateCredentials(user: Authenticatable, credentials: Record<string, string>): Promise<boolean>;
14
+ }
15
+ //# sourceMappingURL=user-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-provider.d.ts","sourceRoot":"","sources":["../src/user-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACnE,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC5F,mBAAmB,CAAC,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnG;AAED,qBAAa,oBAAqB,YAAW,YAAY;IAG3C,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAEV,KAAK,EAAE,oBAAoB;IAElD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAMlE,qBAAqB,CACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAW5B,mBAAmB,CACvB,IAAI,EAAE,eAAe,EACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC;CAQpB"}
@@ -0,0 +1,30 @@
1
+ import { Hasher } from './hasher.js';
2
+ export class EloquentUserProvider {
3
+ model;
4
+ hasher = new Hasher();
5
+ constructor(model) {
6
+ this.model = model;
7
+ }
8
+ async retrieveById(id) {
9
+ const ModelClass = this.model;
10
+ const user = await ModelClass.find(id);
11
+ return user;
12
+ }
13
+ async retrieveByCredentials(credentials) {
14
+ const email = credentials.email;
15
+ if (!email) {
16
+ return null;
17
+ }
18
+ const ModelClass = this.model;
19
+ const user = await ModelClass.query().where('email', email).firstModel();
20
+ return user;
21
+ }
22
+ async validateCredentials(user, credentials) {
23
+ const password = credentials.password;
24
+ if (!password) {
25
+ return false;
26
+ }
27
+ return this.hasher.check(password, user.getAuthPassword());
28
+ }
29
+ }
30
+ //# sourceMappingURL=user-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-provider.js","sourceRoot":"","sources":["../src/user-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrC,MAAM,OAAO,oBAAoB;IAGF;IAFZ,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAEvC,YAA6B,KAA2B;QAA3B,UAAK,GAAL,KAAK,CAAsB;IAAG,CAAC;IAE5D,KAAK,CAAC,YAAY,CAAC,EAAmB;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAgC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO,IAA8B,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,WAAmC;QAEnC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAgC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QACzE,OAAO,IAA8B,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,IAAqB,EACrB,WAAmC;QAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@tyravel/auth",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "typecheck": "tsc -p tsconfig.json --noEmit"
16
+ },
17
+ "dependencies": {
18
+ "@tyravel/container": "0.1.0",
19
+ "@tyravel/database": "0.1.0",
20
+ "@tyravel/http": "0.1.0"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "engines": {
26
+ "node": ">=22"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.15.30"
30
+ },
31
+ "description": "Authentication and authorization for Tyravel",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/thesimonharms/tyravel.git",
36
+ "directory": "packages/auth"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }