Skip to content

Release v4.17 #1220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/basic-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Check
run: ./gradlew spotlessCheck

Expand All @@ -26,7 +26,7 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Check
run: ./gradlew test

Expand All @@ -38,7 +38,7 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/code-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
# Shallow clones should be disabled for a better relevancy of analysis
fetch-depth: 0
Expand All @@ -24,13 +24,13 @@ jobs:
with:
java-version: ${{ env.JAVA_VERSION }}
- name: Cache SonarCloud packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
with:
java-version: ${{ env.JAVA_VERSION }}
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can check out the head.
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/discord-member.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Comment When PR Merged
on:
pull_request:
types:
- closed
branches:
- develop


jobs:
if_merged:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const creator = context.payload.sender.login
const opts = github.rest.issues.listForRepo.endpoint.merge({
...context.issue,
creator,
state: 'all'
})
const issues = await github.paginate(opts)

for (const issue of issues) {
if (issue.number === context.issue.number) {
continue
}

if (issue.pull_request) {
return
}
}
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Congratulations on your first contribution! We're excited to have you on board. Your work will be included in the next release, so stay tuned!
Are you a Together-Java member on Discord? If so, please share your username here. If not, that’s perfectly fine! If you change your mind, here's the link: ${{vars.SERVER_INVITE}}.
Why do we need your username? We’d like to give you a shoutout to show our gratitude!`
})
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build and Publish Docker Image
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Docker Verify
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/releases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
with:
java-version: ${{ env.JAVA_VERSION }}

- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Build shadow jar
run: ./gradlew shadowJar
Expand Down
14 changes: 7 additions & 7 deletions application/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
buildscript {
dependencies {
classpath 'org.xerial:sqlite-jdbc:3.46.1.0'
classpath 'org.xerial:sqlite-jdbc:3.47.1.0'
}
}

Expand Down Expand Up @@ -40,15 +40,15 @@ shadowJar {

dependencies {
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'org.jetbrains:annotations:24.1.0'
implementation 'org.jetbrains:annotations:26.0.1'

implementation project(':database')
implementation project(':utils')
implementation project(':formatter')

implementation 'net.dv8tion:JDA:5.1.0'
implementation 'net.dv8tion:JDA:5.2.1'

implementation 'org.apache.logging.log4j:log4j-core:2.23.0'
implementation 'org.apache.logging.log4j:log4j-core:2.24.3'
runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.18.0'

implementation 'club.minnced:discord-webhooks:0.8.2'
Expand All @@ -75,13 +75,13 @@ dependencies {

implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'

implementation 'org.kohsuke:github-api:1.324'
implementation 'org.kohsuke:github-api:1.326'

implementation 'org.apache.commons:commons-text:1.12.0'
implementation 'com.apptasticsoftware:rssreader:3.8.1'

testImplementation 'org.mockito:mockito-core:5.12.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'
testImplementation 'org.mockito:mockito-core:5.17.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.1'
Expand Down
3 changes: 1 addition & 2 deletions application/config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@
"hack",
"steamcommunity",
"freenitro",
"usd",
"earn",
"^earn",
".exe"
],
"hostWhitelist": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ public void onMessageReceived(MessageReceivedEvent event) {
return;
}

boolean isSafe = !isBotTrapChannel.test(event.getChannel().asTextChannel());
boolean isSafe = true;
if (event.getChannel() instanceof TextChannel textChannel
&& isBotTrapChannel.test(textChannel)) {
isSafe = false;
}

Message message = event.getMessage();
String content = message.getContentDisplay();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private void analyzeToken(String token, AnalyseResults results) {
results.containsSuspiciousKeyword = true;
}

if (!results.containsDollarSign && token.contains("$")) {
if (!results.containsDollarSign && (token.contains("$") || "usd".equalsIgnoreCase(token))) {
results.containsDollarSign = true;
}

Expand Down Expand Up @@ -114,7 +114,13 @@ private boolean containsSuspiciousKeyword(String token) {
return config.getSuspiciousKeywords()
.stream()
.map(keyword -> keyword.toLowerCase(Locale.US))
.anyMatch(preparedToken::contains);
.anyMatch(keyword -> {
// Simple regex-inspired syntax "^foo"
if (startsWith(keyword, '^')) {
return preparedToken.startsWith(keyword.substring(1));
}
return preparedToken.contains(keyword);
});
}

private boolean isHostSimilarToKeyword(String host, String keyword) {
Expand All @@ -140,6 +146,10 @@ private boolean isHostSimilarToKeyword(String host, String keyword) {
return false;
}

private static boolean startsWith(CharSequence text, char prefixToTest) {
return !text.isEmpty() && text.charAt(0) == prefixToTest;
}

private static class AnalyseResults {
private boolean pingsEveryone;
private boolean containsSuspiciousKeyword;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void setUp() {
when(scamConfig.getSuspiciousKeywords())
.thenReturn(Set.of("nitro", "boob", "sexy", "sexi", "esex", "steam", "gift", "onlyfans",
"bitcoin", "btc", "promo", "trader", "trading", "whatsapp", "crypto", "claim",
"teen", "adobe", "hack", "steamcommunity", "freenitro", "usd", "earn", ".exe"));
"teen", "adobe", "hack", "steamcommunity", "freenitro", "^earn", ".exe"));
when(scamConfig.getHostWhitelist()).thenReturn(Set.of("discord.com", "discord.media",
"discordapp.com", "discordapp.net", "discordstatus.com"));
when(scamConfig.getHostBlacklist()).thenReturn(Set.of("bit.ly", "discord.gg", "teletype.in",
Expand All @@ -54,6 +54,18 @@ void detectsRealScam(String scamMessage) {
assertTrue(isScamResult);
}

@ParameterizedTest
@MethodSource("provideRealFalsePositiveMessages")
@DisplayName("Can ignore real false positive messages")
void ignoresFalsePositives(String falsePositiveMessage) {
// GIVEN a real false positive message
// WHEN analyzing it
boolean isScamResult = scamDetector.isScam(falsePositiveMessage);

// THEN does not flag it as scam
assertFalse(isScamResult);
}

@Test
@DisplayName("Can detect messages that contain blacklisted websites as scam")
void detectsBlacklistedWebsite() {
Expand Down Expand Up @@ -227,4 +239,12 @@ private static List<String> provideRealScamMessages() {
"Urgently looking for mods & collab managers https://discord.gg/cryptohireo",
"Check this - https://transfer.sh/get/ajmkh3l7tzop/Setup.exe");
}

private static List<String> provideRealFalsePositiveMessages() {
return List
.of("""
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/anonymous-types""",
"""
And according to quick google search. Median wage is about $23k usd""");
}
}
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'java'
id "com.diffplug.spotless" version "6.25.0"
id "org.sonarqube" version "5.1.0.4882"
id "org.sonarqube" version "6.0.1.5171"
id "name.remal.sonarlint" version "4.2.2"
}

Expand All @@ -10,7 +10,7 @@ version '1.0-SNAPSHOT'

ext {
jooqVersion = '3.19.1'
jacksonVersion = '2.17.0'
jacksonVersion = '2.18.1'
chatGPTVersion = '0.18.0'
}

Expand Down
4 changes: 2 additions & 2 deletions database/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ plugins {
id 'java'
}

var sqliteVersion = "3.46.1.0"
var sqliteVersion = "3.47.1.0"

dependencies {
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation "org.xerial:sqlite-jdbc:${sqliteVersion}"
implementation 'org.flywaydb:flyway-core:10.17.2'
implementation 'org.flywaydb:flyway-core:11.1.0'
implementation "org.jooq:jooq:$jooqVersion"

implementation project(':utils')
Expand Down
2 changes: 1 addition & 1 deletion formatter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies {
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation project(':utils')

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.1'
}
Expand Down
Loading