@stacksjs/defaults 0.75.30 → 0.75.32
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/ai/skills/stacks-actions/SKILL.md +1 -1
- package/ai/skills/stacks-auth/SKILL.md +0 -1
- package/ai/skills/stacks-config/SKILL.md +1 -1
- package/ai/skills/stacks-email/SKILL.md +6 -0
- package/ai/skills/stacks-types/SKILL.md +1 -1
- package/app/Actions/Auth/GenerateAuthenticationAction.ts +2 -2
- package/app/Actions/Auth/VerifyAuthenticationAction.ts +2 -2
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
- package/project/storage/framework/types/src/auth.ts +2 -1
- package/resources/components/NativeComponents.test.ts +7 -0
- package/resources/components/NativeTabBar.stx +6 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-actions
|
|
3
|
-
description: Use when working with Stacks server actions - creating actions in app/Actions/, auto-generated API actions from the useApi model trait, the
|
|
3
|
+
description: Use when working with Stacks server actions - creating actions in app/Actions/, auto-generated API actions from the useApi model trait, the 647 default framework actions (auth, dashboard, commerce, content, deployment, jobs), action request/response handling, or action registration. Covers @stacksjs/actions and storage/framework/defaults/app/Actions/.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
@@ -395,7 +395,6 @@ await authUser.authorize('edit-post', post) // throws if denied
|
|
|
395
395
|
withRefreshToken: false, // fixed browser lifetime, no unused refresh token
|
|
396
396
|
logoutRedirect: '/login?logged_out=1', // local path for HTML logout only
|
|
397
397
|
},
|
|
398
|
-
tokenRotation: 24, // hours
|
|
399
398
|
defaultAbilities: ['*'],
|
|
400
399
|
defaultTokenName: 'auth-token',
|
|
401
400
|
passwordReset: { expire: 60, throttle: 60 }
|
|
@@ -66,7 +66,7 @@ they name: `defineEvents` and `defineListener` from `@stacksjs/events`,
|
|
|
66
66
|
| File | Type | Key Settings |
|
|
67
67
|
|------|------|-------------|
|
|
68
68
|
| `app.ts` | AppConfig | name, env, url, debug, key, timezone, locale |
|
|
69
|
-
| `auth.ts` | AuthConfig | guards, providers,
|
|
69
|
+
| `auth.ts` | AuthConfig | guards, providers, token and browser-session lifetimes, passwordReset |
|
|
70
70
|
| `database.ts` | DatabaseConfig | default driver, connections (sqlite/mysql/postgres/dynamodb), queryLogging |
|
|
71
71
|
| `cache.ts` | CacheConfig | driver('memory'), ttl(3600), maxKeys(-1), redis config |
|
|
72
72
|
| `env.ts` | EnvConfig | validation schemas for env vars |
|
|
@@ -238,6 +238,12 @@ abstract class BaseEmailDriver {
|
|
|
238
238
|
}
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
+
### Mail DNS a deploy publishes
|
|
242
|
+
|
|
243
|
+
With `server.enabled`, `buddy deploy` reconciles the mail domain's DNS through whichever configured provider holds the zone: MX, SPF, DKIM at the selector the server signs under, DMARC (`server.dmarc`), `mail.<domain>`, and the Gmail Postmaster Tools verification TXT when `server.postmaster.google` is set. Writes are surgical: only records the deploy owns are replaced, so other apex TXT (Search Console, other verifications) survive.
|
|
244
|
+
|
|
245
|
+
Postmaster Tools is the only view of why Gmail files mail as spam when SPF, DKIM and DMARC all pass. Its value is issued per Google account and cannot be generated: add the domain at https://postmaster.google.com, copy the TXT value, set `server.postmaster.google`, deploy, then press Verify in Postmaster Tools. Until it is set the deploy prints where to get it; `postmaster: false` silences that.
|
|
246
|
+
|
|
241
247
|
## Application Mail Example
|
|
242
248
|
|
|
243
249
|
```typescript
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { PublicKeyCredentialRequestOptionsJSON } from '@stacksjs/auth'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import {
|
|
4
|
+
findAuthUserByEmail,
|
|
4
5
|
generateAuthenticationOptions,
|
|
5
6
|
getUserPasskeys,
|
|
6
7
|
passkeyDescriptors,
|
|
7
8
|
storeWebAuthnChallenge,
|
|
8
9
|
} from '@stacksjs/auth'
|
|
9
10
|
import { config } from '@stacksjs/config'
|
|
10
|
-
import { User } from '@stacksjs/orm'
|
|
11
11
|
|
|
12
12
|
export default new Action({
|
|
13
13
|
name: 'PasskeyAuthenticationAction',
|
|
@@ -20,7 +20,7 @@ export default new Action({
|
|
|
20
20
|
return Response.json({ error: 'Email is required' }, { status: 422 })
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const user = await
|
|
23
|
+
const user = await findAuthUserByEmail(email)
|
|
24
24
|
|
|
25
25
|
if (!user) {
|
|
26
26
|
return Response.json({ error: 'User not found' }, { status: 404 })
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Auth,
|
|
5
5
|
authCookieForBrowserSession,
|
|
6
6
|
consumeWebAuthnChallenge,
|
|
7
|
+
findAuthUserByEmail,
|
|
7
8
|
getUserPasskey,
|
|
8
9
|
resolveBrowserSessionPolicy,
|
|
9
10
|
updatePasskeyCounter,
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
} from '@stacksjs/auth'
|
|
12
13
|
import { config } from '@stacksjs/config'
|
|
13
14
|
import { response } from '@stacksjs/router'
|
|
14
|
-
import { User } from '@stacksjs/orm'
|
|
15
15
|
|
|
16
16
|
export default new Action({
|
|
17
17
|
name: 'VerifyAuthenticationAction',
|
|
@@ -23,7 +23,7 @@ export default new Action({
|
|
|
23
23
|
|
|
24
24
|
const email = request.get('email') ?? ''
|
|
25
25
|
|
|
26
|
-
const user = await
|
|
26
|
+
const user = await findAuthUserByEmail(email)
|
|
27
27
|
|
|
28
28
|
if (!user)
|
|
29
29
|
return response.notFound('User not found')
|
package/ide/vscode/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.32",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.27",
|
|
58
|
-
"@stacksjs/mobile": "^0.75.
|
|
58
|
+
"@stacksjs/mobile": "^0.75.32",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.113",
|
|
60
60
|
"ts-qr-codes": "^0.1.8"
|
|
61
61
|
}
|
|
@@ -19,7 +19,8 @@ export interface AuthConfig {
|
|
|
19
19
|
username: string
|
|
20
20
|
password: string
|
|
21
21
|
tokenExpiry: number
|
|
22
|
-
|
|
22
|
+
/** @deprecated Use explicit bearer rotation or a refresh-token exchange. */
|
|
23
|
+
tokenRotation?: number
|
|
23
24
|
defaultAbilities: string[]
|
|
24
25
|
defaultTokenName: string
|
|
25
26
|
}
|
|
@@ -20,6 +20,13 @@ describe('Native components', () => {
|
|
|
20
20
|
expect(item).toContain('draggable="false"')
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
+
it('centres each tab in the bar rather than against its top border', () => {
|
|
24
|
+
// stx wraps each NativeTabItem in a scope box; the box stretched while
|
|
25
|
+
// the link inside kept its own height, so icons sat on the border.
|
|
26
|
+
const bar = read('NativeTabBar')
|
|
27
|
+
expect(bar).toContain('.native-tab-bar > [data-stx-scope]:has(> .native-tab-item) { display: contents; }')
|
|
28
|
+
})
|
|
29
|
+
|
|
23
30
|
it('shows the offline banner by class, so it can come back', () => {
|
|
24
31
|
const banner = read('NativeNetworkBanner')
|
|
25
32
|
expect(banner).not.toContain(':if="!connected()"')
|
|
@@ -19,6 +19,12 @@ function selectTab(): void {
|
|
|
19
19
|
</nav>
|
|
20
20
|
|
|
21
21
|
<style>
|
|
22
|
+
/* Each tab is a component, and stx wraps a component in a box of its own:
|
|
23
|
+
that box stretched to the bar's height while the link inside kept the
|
|
24
|
+
height of its icon and label, pressed against the bar's top border. The
|
|
25
|
+
box steps aside, so the link is the grid item and centres in the bar. */
|
|
26
|
+
.native-tab-bar > [data-stx-scope]:has(> .native-tab-item) { display: contents; }
|
|
27
|
+
|
|
22
28
|
.native-tab-bar {
|
|
23
29
|
display: grid;
|
|
24
30
|
grid-auto-flow: column;
|