diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index c1637284..6cdea914 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -141,7 +141,7 @@ jobs: sdk: stable - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: "1.26.6" + go-version: "1.26.9" - name: Install OSV Scanner run: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@${{ env.OSV_SCANNER_VERSION }} - name: Audit Dart templates @@ -167,7 +167,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: "1.26.6" + go-version: "1.26.9" cache: false - name: Install govulncheck run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 @@ -247,7 +247,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: "1.26.6" + go-version: "1.26.9" - name: Install OSV Scanner run: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@${{ env.OSV_SCANNER_VERSION }} - name: Audit Maven coordinates in deps.gradle diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f4f93d3a..5032e4f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -183,7 +183,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: "1.26.6" + go-version: "1.26.9" cache: false - name: Build templates run: for dir in go/*/; do [ ! -f "${dir}go.mod" ] || (cd "$dir" && go build ./...); done diff --git a/node/email-contact-form/package-lock.json b/node/email-contact-form/package-lock.json index c567f0a6..fbc2c797 100644 --- a/node/email-contact-form/package-lock.json +++ b/node/email-contact-form/package-lock.json @@ -12,6 +12,9 @@ }, "devDependencies": { "prettier": "^3.2.5" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/nodemailer": { diff --git a/node/email-contact-form/package.json b/node/email-contact-form/package.json index 52c3e71d..4edd6ce0 100644 --- a/node/email-contact-form/package.json +++ b/node/email-contact-form/package.json @@ -12,5 +12,8 @@ }, "devDependencies": { "prettier": "^3.2.5" + }, + "engines": { + "node": ">=20.0.0" } } diff --git a/node/generate-pdf/package-lock.json b/node/generate-pdf/package-lock.json index 9ab8b155..bf5a33be 100644 --- a/node/generate-pdf/package-lock.json +++ b/node/generate-pdf/package-lock.json @@ -13,6 +13,9 @@ }, "devDependencies": { "prettier": "^3.2.5" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0" } }, "node_modules/@faker-js/faker": { diff --git a/node/generate-pdf/package.json b/node/generate-pdf/package.json index 7bd93818..33363bac 100644 --- a/node/generate-pdf/package.json +++ b/node/generate-pdf/package.json @@ -13,5 +13,8 @@ }, "devDependencies": { "prettier": "^3.2.5" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0" } } diff --git a/node/password-expiry/README.md b/node/password-expiry/README.md index 602bf498..00b706cf 100644 --- a/node/password-expiry/README.md +++ b/node/password-expiry/README.md @@ -45,8 +45,8 @@ You can set CRON to control how often the function is executed. For example, `0 The maximum number of days a password can be used before the user is forced to change it. -| Question | Answer | -| ------------- | --------------------- | -| Required | No | -| Default Value | `90` | -| Sample Value | `https://short.app/s` | +| Question | Answer | +| ------------- | ------ | +| Required | No | +| Default Value | `90` | +| Sample Value | `90` | diff --git a/node/password-expiry/package-lock.json b/node/password-expiry/package-lock.json index b612d372..d512babc 100644 --- a/node/password-expiry/package-lock.json +++ b/node/password-expiry/package-lock.json @@ -15,7 +15,7 @@ "prettier": "^3.2.5" }, "engines": { - "node": ">=18.17.0" + "node": ">=20.0.0" } }, "node_modules/bignumber.js": { diff --git a/node/password-expiry/package.json b/node/password-expiry/package.json index f9ceb796..512c3db2 100644 --- a/node/password-expiry/package.json +++ b/node/password-expiry/package.json @@ -15,6 +15,6 @@ "prettier": "^3.2.5" }, "engines": { - "node": ">=18.17.0" + "node": ">=20.0.0" } } diff --git a/node/password-expiry/src/main.js b/node/password-expiry/src/main.js index 72e903c0..3eed3e48 100644 --- a/node/password-expiry/src/main.js +++ b/node/password-expiry/src/main.js @@ -5,7 +5,6 @@ import nodemailer from 'nodemailer'; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ 'APPWRITE_FUNCTION_PROJECT_ID', - 'MAX_PASSWORD_AGE', 'RESET_PASSWORD_URL', 'STMP_DSN', ]); @@ -18,13 +17,24 @@ export default async ({ req, res, log, error }) => { const users = new Users(client); - const expiryPeriodMs = 1000; + const maxPasswordAgeDays = Number(process.env.MAX_PASSWORD_AGE || 90); + const expiryPeriodMs = maxPasswordAgeDays * 24 * 60 * 60 * 1000; const beforeTimeMs = Date.now() - expiryPeriodMs; const beforeDateTime = new Date(beforeTimeMs).toISOString(); - const usersWithExpiredPasswords = await users.list([ - Query.lessThanEqual('passwordUpdate', beforeDateTime), - ]); + const usersWithExpiredPasswords = []; + let cursor; + do { + const queries = [ + Query.lessThanEqual('passwordUpdate', beforeDateTime), + Query.limit(100), + ]; + if (cursor) queries.push(Query.cursorAfter(cursor)); + + const page = await users.list({ queries, total: false }); + usersWithExpiredPasswords.push(...page.users); + cursor = page.users.length === 100 ? page.users[99].$id : undefined; + } while (cursor); const dsn = new URL(process.env.STMP_DSN); @@ -51,7 +61,7 @@ export default async ({ req, res, log, error }) => { try { await transport.sendMail({ from: dsn.searchParams.get('from'), - to: 'luke@appwrite.io', + to: user.email, subject: 'Your password needs to be updated', text: `Hi ${ user.name