Skip to content
Open
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: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ coverage/
# Temporary files
*.tmp
*.temp
docs/

# Cursor
memory-bank/
.cursor/

1 change: 1 addition & 0 deletions st-app-cms/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ ADMIN_JWT_SECRET=tobemodified
TRANSFER_TOKEN_SALT=tobemodified
JWT_SECRET=tobemodified
ENCRYPTION_KEY=tobemodified
NEXT_SERVER_API_TOKEN=ebab379d647f6afd984a390254830a120f5592a6052337abac544b2239a774e17a24144f04e09b8986e39bf34523b1bf4cc639003de6f551f07a088abfaf617dd62195f0cc95e04909ea714d62848b93aeb94daa555613e2e13084a11e71c21453d7cadecdb1a7a7fd50400762fc2c479277d2bfcfde36dbaac6fb18f38342bf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not look like example

64 changes: 56 additions & 8 deletions st-app-cms/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions st-app-cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@
"@strapi/strapi": "5.17.0",
"better-sqlite3": "11.3.0",
"fs-extra": "^10.0.0",
"koa-bodyparser": "^4.4.1",
"mime-types": "^2.1.27",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.0.0",
"styled-components": "^6.0.0"
},
"devDependencies": {
"@types/koa": "^3.0.0",
"@types/koa-bodyparser": "^4.3.12",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
Expand Down
22 changes: 22 additions & 0 deletions st-app-cms/src/api/course/content-types/course/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"kind": "collectionType",
"collectionName": "courses",
"info": {
"singularName": "course",
"pluralName": "courses",
"displayName": "Course"
},
"options": {
"draftAndPublish": true
},
"pluginOptions": {},
"attributes": {
"name": {
"type": "string",
"required": true
},
"description": {
"type": "richtext"
}
}
}
7 changes: 7 additions & 0 deletions st-app-cms/src/api/course/controllers/course.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* course controller
*/

import { factories } from '@strapi/strapi'

export default factories.createCoreController('api::course.course');
7 changes: 7 additions & 0 deletions st-app-cms/src/api/course/routes/course.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* course router
*/

import { factories } from '@strapi/strapi';

export default factories.createCoreRouter('api::course.course');
7 changes: 7 additions & 0 deletions st-app-cms/src/api/course/services/course.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* course service
*/

import { factories } from '@strapi/strapi';

export default factories.createCoreService('api::course.course');
19 changes: 19 additions & 0 deletions st-app-cms/src/api/github-login/controllers/github-login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import LoginContext from "../interfaces/login-context";
import BaseUser, { baseUserFields } from "../interfaces/user";
import loginService from '../services/github-login';

export default {
async create(ctx: LoginContext) {
const { githubId, email } = ctx.request.body;

if (!githubId || !email) {
return ctx.badRequest('Missing githubUsername or email');
}
try {
const user: BaseUser & {created: boolean} = await loginService.loginUser({ githubId, email });
return ctx.send(user, user.created ? 201 : 200);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be more readable if you first calculate the status code, and then just pass it to send it like

const statusCode = user.created ? CREATED : OK;

return ctx.send(user, statusCode);

} catch (error) {
return ctx.internalServerError('Internal error');
}
},
};
10 changes: 10 additions & 0 deletions st-app-cms/src/api/github-login/interfaces/login-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Context } from 'koa';
import LoginDto from './login-dto';

export default interface LoginContext extends Context {
request: Context['request'] & {
body: LoginDto;
};
}


4 changes: 4 additions & 0 deletions st-app-cms/src/api/github-login/interfaces/login-dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default interface LoginDto {
githubId: string | null;
email: string | null;
}
7 changes: 7 additions & 0 deletions st-app-cms/src/api/github-login/interfaces/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default interface BaseUser {
id: number;
username: string;
email: string;
}

export const baseUserFields: (keyof BaseUser)[] = ['id', 'username', 'email'];
20 changes: 20 additions & 0 deletions st-app-cms/src/api/github-login/routes/github-login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Core } from '@strapi/types';

type Route = Core.RouteInput
type Routes = {
routes: Route[]
}

export default {
routes: [
{
method: 'POST',
path: '/github-login',
handler: 'github-login.create',
config: {
policies: ['global::next-server-api-token'],
auth: false,
},
},
],
} satisfies Routes
30 changes: 30 additions & 0 deletions st-app-cms/src/api/github-login/services/github-login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import LoginDto from "../interfaces/login-dto";
import BaseUser, { baseUserFields } from "../interfaces/user";

const loginUser = async ({ githubId, email }: LoginDto) => {
const existingUser = await strapi.db.query('plugin::users-permissions.user').findOne({
select: baseUserFields,
where: { username: githubId },
});

if (existingUser) {
return {
...existingUser satisfies BaseUser,
created: false,
};
}

const newUser = await strapi.db.query('plugin::users-permissions.user').create({
select: baseUserFields,
data: { username: githubId, email, confirmed: true },
});

return {
...newUser satisfies BaseUser,
created: true,
};
};

export default {
loginUser,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"kind": "collectionType",
"collectionName": "up_users",
"info": {
"name": "user",
"description": "",
"singularName": "user",
"pluralName": "users",
"displayName": "User"
},
"options": {
"draftAndPublish": false
},
"pluginOptions": {},
"attributes": {
"username": {
"type": "string",
"minLength": 3,
"unique": true,
"configurable": false,
"required": true
},
"email": {
"type": "email",
"minLength": 6,
"configurable": false,
"required": true
},
"provider": {
"type": "string",
"configurable": false
},
"password": {
"type": "password",
"minLength": 6,
"configurable": false,
"private": true,
"searchable": false
},
"resetPasswordToken": {
"type": "string",
"configurable": false,
"private": true,
"searchable": false
},
"confirmationToken": {
"type": "string",
"configurable": false,
"private": true,
"searchable": false
},
"confirmed": {
"type": "boolean",
"default": false,
"configurable": false
},
"blocked": {
"type": "boolean",
"default": false,
"configurable": false
},
"role": {
"type": "relation",
"relation": "manyToOne",
"target": "plugin::users-permissions.role",
"inversedBy": "users",
"configurable": false
}
}
}
7 changes: 5 additions & 2 deletions st-app-cms/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// import type { Core } from '@strapi/strapi';
import type { Core } from '@strapi/strapi';

export default {
/**
Expand All @@ -7,7 +7,10 @@ export default {
*
* This gives you an opportunity to extend code.
*/
register(/* { strapi }: { strapi: Core.Strapi } */) {},
register({ strapi }: { strapi: Core.Strapi }) {
strapi.get('policies').set('next-server-api-token', require('./policies/next-server-api-token').default);
},


/**
* An asynchronous bootstrap function that runs before
Expand Down
Loading