@stravigor/oauth2 0.4.5

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.
package/src/utils.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Extract a user ID from any user object.
3
+ *
4
+ * Unlike `extractUserId` from `@stravigor/core/helpers` which requires a
5
+ * BaseModel instance, this helper works with plain objects (e.g. `{ id: 1 }`)
6
+ * so that `@stravigor/oauth2` stays user-type agnostic.
7
+ */
8
+ export function getUserId(user: unknown): string {
9
+ if (typeof user === 'string') return user
10
+ if (typeof user === 'number') return String(user)
11
+ if (user && typeof user === 'object' && 'id' in user) {
12
+ return String((user as Record<string, unknown>).id)
13
+ }
14
+ throw new Error('Cannot extract user ID: user must have an "id" property or be a string/number.')
15
+ }
@@ -0,0 +1,28 @@
1
+ import { defineActions } from '@stravigor/oauth2'
2
+ // import { User } from '../models/user'
3
+
4
+ export default defineActions({
5
+ /**
6
+ * Find a user by their primary key.
7
+ * Used to load the resource owner for token-protected routes.
8
+ */
9
+ async findById(id) {
10
+ // return User.find(id)
11
+ throw new Error('Implement findById in actions/oauth2.ts')
12
+ },
13
+
14
+ /**
15
+ * Return the user's display identifier.
16
+ * Shown on the consent screen for third-party clients.
17
+ */
18
+ identifierOf(user) {
19
+ // return user.email
20
+ throw new Error('Implement identifierOf in actions/oauth2.ts')
21
+ },
22
+
23
+ // ─── Optional: Custom consent screen ─────────────────────────────────
24
+ //
25
+ // renderAuthorization(ctx, client, scopes) {
26
+ // return ctx.view('oauth/authorize', { client, scopes })
27
+ // },
28
+ })
@@ -0,0 +1,35 @@
1
+ import { env } from '@stravigor/core/helpers'
2
+
3
+ export default {
4
+ // Token lifetimes (in minutes)
5
+ accessTokenLifetime: 60, // 1 hour
6
+ refreshTokenLifetime: 43_200, // 30 days
7
+ authCodeLifetime: 10, // 10 minutes
8
+ personalAccessTokenLifetime: 525_600, // 1 year
9
+
10
+ // Route prefix for all OAuth2 endpoints
11
+ prefix: '/oauth',
12
+
13
+ // Available scopes — define your app's scopes here
14
+ scopes: {
15
+ // 'read': 'Read access to your data',
16
+ // 'write': 'Write access to your data',
17
+ // 'repos:read': 'Read your repositories',
18
+ // 'repos:write': 'Create and update repositories',
19
+ },
20
+
21
+ // Scopes granted when none are explicitly requested
22
+ defaultScopes: [] as string[],
23
+
24
+ // Client ID for personal access tokens (created by `strav oauth2:setup`)
25
+ personalAccessClient: env('OAUTH2_PERSONAL_CLIENT') ?? null,
26
+
27
+ // Rate limiting
28
+ rateLimit: {
29
+ authorize: { max: 30, window: 60 }, // 30 requests per 60 seconds
30
+ token: { max: 20, window: 60 }, // 20 requests per 60 seconds
31
+ },
32
+
33
+ // Cleanup: delete revoked tokens older than this many days
34
+ pruneRevokedAfterDays: 7,
35
+ }
@@ -0,0 +1,16 @@
1
+ import { defineSchema, t, Archetype } from '@stravigor/core/schema'
2
+
3
+ export default defineSchema('oauth_auth_code', {
4
+ archetype: Archetype.Event,
5
+ fields: {
6
+ clientId: t.uuid().required().index(),
7
+ userId: t.varchar(255).required().index(),
8
+ code: t.varchar(255).required().unique(),
9
+ redirectUri: t.varchar(2048).required(),
10
+ scopes: t.jsonb().required(),
11
+ codeChallenge: t.varchar(255).nullable(),
12
+ codeChallengeMethod: t.varchar(10).nullable(),
13
+ expiresAt: t.timestamptz().required(),
14
+ usedAt: t.timestamptz().nullable(),
15
+ },
16
+ })
@@ -0,0 +1,15 @@
1
+ import { defineSchema, t, Archetype } from '@stravigor/core/schema'
2
+
3
+ export default defineSchema('oauth_client', {
4
+ archetype: Archetype.Entity,
5
+ fields: {
6
+ name: t.varchar(255).required(),
7
+ secret: t.varchar(255).nullable(),
8
+ redirectUris: t.jsonb().required(),
9
+ scopes: t.jsonb().nullable(),
10
+ grantTypes: t.jsonb().required(),
11
+ confidential: t.boolean().required(),
12
+ firstParty: t.boolean().required(),
13
+ revoked: t.boolean().required(),
14
+ },
15
+ })
@@ -0,0 +1,17 @@
1
+ import { defineSchema, t, Archetype } from '@stravigor/core/schema'
2
+
3
+ export default defineSchema('oauth_token', {
4
+ archetype: Archetype.Component,
5
+ parent: 'user',
6
+ fields: {
7
+ clientId: t.uuid().required().index(),
8
+ name: t.varchar(255).nullable(),
9
+ scopes: t.jsonb().required(),
10
+ token: t.varchar(255).required().unique(),
11
+ refreshToken: t.varchar(255).nullable().unique(),
12
+ expiresAt: t.timestamptz().required(),
13
+ refreshExpiresAt: t.timestamptz().nullable(),
14
+ lastUsedAt: t.timestamptz().nullable(),
15
+ revokedAt: t.timestamptz().nullable(),
16
+ },
17
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*.ts"]
4
+ }